reflex 0.6.4a3__py3-none-any.whl → 0.6.5a1__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.
Files changed (228) hide show
  1. reflex/.templates/jinja/web/pages/custom_component.js.jinja2 +0 -14
  2. reflex/.templates/jinja/web/pages/utils.js.jinja2 +4 -8
  3. reflex/.templates/web/components/shiki/code.js +16 -11
  4. reflex/.templates/web/utils/state.js +29 -21
  5. reflex/__init__.py +4 -0
  6. reflex/__init__.pyi +4 -0
  7. reflex/app.py +148 -154
  8. reflex/app_mixins/lifespan.py +5 -1
  9. reflex/app_mixins/middleware.py +3 -1
  10. reflex/app_mixins/mixin.py +3 -2
  11. reflex/base.py +2 -4
  12. reflex/compiler/compiler.py +111 -37
  13. reflex/components/base/app_wrap.pyi +17 -17
  14. reflex/components/base/bare.py +72 -3
  15. reflex/components/base/body.pyi +17 -17
  16. reflex/components/base/document.pyi +81 -81
  17. reflex/components/base/error_boundary.pyi +25 -18
  18. reflex/components/base/fragment.pyi +17 -17
  19. reflex/components/base/head.pyi +33 -33
  20. reflex/components/base/link.pyi +33 -33
  21. reflex/components/base/meta.pyi +65 -65
  22. reflex/components/base/script.py +4 -4
  23. reflex/components/base/script.pyi +23 -20
  24. reflex/components/component.py +250 -31
  25. reflex/components/core/banner.py +1 -1
  26. reflex/components/core/banner.pyi +81 -81
  27. reflex/components/core/client_side_routing.pyi +33 -33
  28. reflex/components/core/clipboard.py +2 -2
  29. reflex/components/core/clipboard.pyi +24 -18
  30. reflex/components/core/debounce.py +2 -2
  31. reflex/components/core/debounce.pyi +18 -18
  32. reflex/components/core/html.pyi +17 -17
  33. reflex/components/core/upload.py +82 -28
  34. reflex/components/core/upload.pyi +77 -72
  35. reflex/components/datadisplay/code.py +55 -40
  36. reflex/components/datadisplay/code.pyi +46 -44
  37. reflex/components/datadisplay/dataeditor.py +21 -20
  38. reflex/components/datadisplay/dataeditor.pyi +103 -35
  39. reflex/components/datadisplay/shiki_code_block.py +60 -27
  40. reflex/components/datadisplay/shiki_code_block.pyi +86 -65
  41. reflex/components/dynamic.py +9 -5
  42. reflex/components/el/element.pyi +17 -17
  43. reflex/components/el/elements/base.pyi +17 -17
  44. reflex/components/el/elements/forms.py +12 -3
  45. reflex/components/el/elements/forms.pyi +293 -233
  46. reflex/components/el/elements/inline.pyi +449 -449
  47. reflex/components/el/elements/media.pyi +401 -401
  48. reflex/components/el/elements/metadata.pyi +97 -97
  49. reflex/components/el/elements/other.pyi +113 -113
  50. reflex/components/el/elements/scripts.pyi +49 -49
  51. reflex/components/el/elements/sectioning.pyi +241 -241
  52. reflex/components/el/elements/tables.pyi +161 -161
  53. reflex/components/el/elements/typography.pyi +241 -241
  54. reflex/components/gridjs/datatable.pyi +33 -33
  55. reflex/components/lucide/icon.py +1 -1
  56. reflex/components/lucide/icon.pyi +33 -33
  57. reflex/components/markdown/markdown.py +180 -49
  58. reflex/components/markdown/markdown.pyi +36 -19
  59. reflex/components/moment/moment.py +17 -21
  60. reflex/components/moment/moment.pyi +26 -21
  61. reflex/components/next/base.pyi +17 -17
  62. reflex/components/next/image.py +3 -3
  63. reflex/components/next/image.pyi +21 -19
  64. reflex/components/next/link.pyi +17 -17
  65. reflex/components/next/video.pyi +17 -17
  66. reflex/components/plotly/plotly.py +79 -78
  67. reflex/components/plotly/plotly.pyi +91 -41
  68. reflex/components/props.py +34 -0
  69. reflex/components/radix/primitives/accordion.py +15 -8
  70. reflex/components/radix/primitives/accordion.pyi +121 -118
  71. reflex/components/radix/primitives/base.pyi +33 -33
  72. reflex/components/radix/primitives/drawer.py +41 -20
  73. reflex/components/radix/primitives/drawer.pyi +279 -190
  74. reflex/components/radix/primitives/form.py +2 -2
  75. reflex/components/radix/primitives/form.pyi +200 -167
  76. reflex/components/radix/primitives/progress.pyi +81 -81
  77. reflex/components/radix/primitives/slider.pyi +89 -83
  78. reflex/components/radix/themes/base.py +27 -1
  79. reflex/components/radix/themes/base.pyi +286 -113
  80. reflex/components/radix/themes/color_mode.py +17 -9
  81. reflex/components/radix/themes/color_mode.pyi +68 -56
  82. reflex/components/radix/themes/components/alert_dialog.py +8 -5
  83. reflex/components/radix/themes/components/alert_dialog.pyi +125 -117
  84. reflex/components/radix/themes/components/aspect_ratio.pyi +17 -17
  85. reflex/components/radix/themes/components/avatar.py +1 -5
  86. reflex/components/radix/themes/components/avatar.pyi +17 -17
  87. reflex/components/radix/themes/components/badge.py +1 -5
  88. reflex/components/radix/themes/components/badge.pyi +17 -17
  89. reflex/components/radix/themes/components/button.pyi +18 -21
  90. reflex/components/radix/themes/components/callout.py +1 -4
  91. reflex/components/radix/themes/components/callout.pyi +81 -81
  92. reflex/components/radix/themes/components/card.py +1 -3
  93. reflex/components/radix/themes/components/card.pyi +17 -17
  94. reflex/components/radix/themes/components/checkbox.py +4 -8
  95. reflex/components/radix/themes/components/checkbox.pyi +61 -52
  96. reflex/components/radix/themes/components/checkbox_cards.pyi +33 -33
  97. reflex/components/radix/themes/components/checkbox_group.pyi +33 -33
  98. reflex/components/radix/themes/components/context_menu.py +121 -28
  99. reflex/components/radix/themes/components/context_menu.pyi +250 -147
  100. reflex/components/radix/themes/components/data_list.pyi +65 -65
  101. reflex/components/radix/themes/components/dialog.py +11 -11
  102. reflex/components/radix/themes/components/dialog.pyi +135 -120
  103. reflex/components/radix/themes/components/dropdown_menu.py +14 -25
  104. reflex/components/radix/themes/components/dropdown_menu.pyi +157 -145
  105. reflex/components/radix/themes/components/hover_card.py +19 -7
  106. reflex/components/radix/themes/components/hover_card.pyi +102 -67
  107. reflex/components/radix/themes/components/icon_button.pyi +18 -21
  108. reflex/components/radix/themes/components/inset.py +1 -3
  109. reflex/components/radix/themes/components/inset.pyi +17 -17
  110. reflex/components/radix/themes/components/popover.py +22 -13
  111. reflex/components/radix/themes/components/popover.pyi +98 -72
  112. reflex/components/radix/themes/components/progress.pyi +17 -17
  113. reflex/components/radix/themes/components/radio.pyi +17 -17
  114. reflex/components/radix/themes/components/radio_cards.py +2 -2
  115. reflex/components/radix/themes/components/radio_cards.pyi +37 -34
  116. reflex/components/radix/themes/components/radio_group.py +3 -7
  117. reflex/components/radix/themes/components/radio_group.pyi +69 -66
  118. reflex/components/radix/themes/components/scroll_area.py +1 -3
  119. reflex/components/radix/themes/components/scroll_area.pyi +17 -17
  120. reflex/components/radix/themes/components/segmented_control.pyi +37 -34
  121. reflex/components/radix/themes/components/select.py +7 -11
  122. reflex/components/radix/themes/components/select.pyi +175 -154
  123. reflex/components/radix/themes/components/separator.py +1 -4
  124. reflex/components/radix/themes/components/separator.pyi +17 -17
  125. reflex/components/radix/themes/components/skeleton.pyi +17 -17
  126. reflex/components/radix/themes/components/slider.py +12 -21
  127. reflex/components/radix/themes/components/slider.pyi +47 -25
  128. reflex/components/radix/themes/components/spinner.py +1 -4
  129. reflex/components/radix/themes/components/spinner.pyi +17 -17
  130. reflex/components/radix/themes/components/switch.py +3 -6
  131. reflex/components/radix/themes/components/switch.pyi +21 -18
  132. reflex/components/radix/themes/components/table.py +21 -5
  133. reflex/components/radix/themes/components/table.pyi +392 -116
  134. reflex/components/radix/themes/components/tabs.py +3 -6
  135. reflex/components/radix/themes/components/tabs.pyi +89 -83
  136. reflex/components/radix/themes/components/text_area.py +1 -5
  137. reflex/components/radix/themes/components/text_area.pyi +43 -20
  138. reflex/components/radix/themes/components/text_field.py +1 -5
  139. reflex/components/radix/themes/components/text_field.pyi +101 -55
  140. reflex/components/radix/themes/components/tooltip.py +5 -7
  141. reflex/components/radix/themes/components/tooltip.pyi +25 -22
  142. reflex/components/radix/themes/layout/base.py +2 -27
  143. reflex/components/radix/themes/layout/base.pyi +82 -82
  144. reflex/components/radix/themes/layout/box.pyi +17 -17
  145. reflex/components/radix/themes/layout/center.pyi +17 -17
  146. reflex/components/radix/themes/layout/container.pyi +17 -17
  147. reflex/components/radix/themes/layout/flex.py +1 -6
  148. reflex/components/radix/themes/layout/flex.pyi +17 -17
  149. reflex/components/radix/themes/layout/grid.py +1 -6
  150. reflex/components/radix/themes/layout/grid.pyi +17 -17
  151. reflex/components/radix/themes/layout/list.py +20 -15
  152. reflex/components/radix/themes/layout/list.pyi +175 -92
  153. reflex/components/radix/themes/layout/section.pyi +17 -17
  154. reflex/components/radix/themes/layout/spacer.pyi +17 -17
  155. reflex/components/radix/themes/layout/stack.py +6 -6
  156. reflex/components/radix/themes/layout/stack.pyi +91 -62
  157. reflex/components/radix/themes/typography/blockquote.py +2 -8
  158. reflex/components/radix/themes/typography/blockquote.pyi +17 -17
  159. reflex/components/radix/themes/typography/code.py +4 -10
  160. reflex/components/radix/themes/typography/code.pyi +19 -18
  161. reflex/components/radix/themes/typography/heading.py +4 -11
  162. reflex/components/radix/themes/typography/heading.pyi +19 -18
  163. reflex/components/radix/themes/typography/link.py +4 -10
  164. reflex/components/radix/themes/typography/link.pyi +19 -18
  165. reflex/components/radix/themes/typography/text.py +4 -11
  166. reflex/components/radix/themes/typography/text.pyi +115 -114
  167. reflex/components/react_player/audio.pyi +58 -33
  168. reflex/components/react_player/react_player.py +17 -17
  169. reflex/components/react_player/react_player.pyi +55 -33
  170. reflex/components/react_player/video.pyi +58 -33
  171. reflex/components/recharts/cartesian.py +45 -45
  172. reflex/components/recharts/cartesian.pyi +389 -304
  173. reflex/components/recharts/charts.py +22 -22
  174. reflex/components/recharts/charts.pyi +226 -179
  175. reflex/components/recharts/general.py +26 -27
  176. reflex/components/recharts/general.pyi +106 -99
  177. reflex/components/recharts/polar.py +33 -33
  178. reflex/components/recharts/polar.pyi +70 -64
  179. reflex/components/recharts/recharts.pyi +33 -33
  180. reflex/components/sonner/toast.py +9 -36
  181. reflex/components/sonner/toast.pyi +20 -24
  182. reflex/components/suneditor/editor.py +8 -8
  183. reflex/components/suneditor/editor.pyi +50 -25
  184. reflex/components/tags/iter_tag.py +1 -10
  185. reflex/components/tags/tag.py +1 -4
  186. reflex/config.py +198 -35
  187. reflex/constants/__init__.py +4 -16
  188. reflex/constants/base.py +7 -14
  189. reflex/constants/colors.py +0 -1
  190. reflex/constants/installer.py +12 -7
  191. reflex/constants/state.py +4 -0
  192. reflex/custom_components/custom_components.py +6 -6
  193. reflex/event.py +486 -241
  194. reflex/experimental/client_state.py +9 -9
  195. reflex/experimental/layout.py +2 -2
  196. reflex/experimental/layout.pyi +95 -87
  197. reflex/experimental/misc.py +1 -1
  198. reflex/istate/__init__.py +1 -0
  199. reflex/istate/proxy.py +33 -0
  200. reflex/istate/wrappers.py +27 -0
  201. reflex/model.py +7 -7
  202. reflex/page.py +2 -1
  203. reflex/reflex.py +142 -8
  204. reflex/state.py +127 -46
  205. reflex/testing.py +9 -7
  206. reflex/utils/console.py +0 -1
  207. reflex/utils/exceptions.py +31 -3
  208. reflex/utils/exec.py +33 -14
  209. reflex/utils/format.py +15 -12
  210. reflex/utils/net.py +1 -1
  211. reflex/utils/path_ops.py +2 -2
  212. reflex/utils/prerequisites.py +82 -46
  213. reflex/utils/pyi_generator.py +63 -20
  214. reflex/utils/registry.py +1 -1
  215. reflex/utils/serializers.py +75 -36
  216. reflex/utils/telemetry.py +3 -2
  217. reflex/utils/types.py +125 -10
  218. reflex/vars/base.py +131 -119
  219. reflex/vars/function.py +59 -12
  220. reflex/vars/number.py +3 -1
  221. reflex/vars/object.py +30 -24
  222. reflex/vars/sequence.py +7 -7
  223. {reflex-0.6.4a3.dist-info → reflex-0.6.5a1.dist-info}/METADATA +3 -3
  224. reflex-0.6.5a1.dist-info/RECORD +394 -0
  225. reflex-0.6.4a3.dist-info/RECORD +0 -391
  226. {reflex-0.6.4a3.dist-info → reflex-0.6.5a1.dist-info}/LICENSE +0 -0
  227. {reflex-0.6.4a3.dist-info → reflex-0.6.5a1.dist-info}/WHEEL +0 -0
  228. {reflex-0.6.4a3.dist-info → reflex-0.6.5a1.dist-info}/entry_points.txt +0 -0
@@ -3,6 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import copy
6
+ import dataclasses
6
7
  import typing
7
8
  from abc import ABC, abstractmethod
8
9
  from functools import lru_cache, wraps
@@ -16,6 +17,7 @@ from typing import (
16
17
  Iterator,
17
18
  List,
18
19
  Optional,
20
+ Sequence,
19
21
  Set,
20
22
  Type,
21
23
  Union,
@@ -37,6 +39,7 @@ from reflex.constants import (
37
39
  PageNames,
38
40
  )
39
41
  from reflex.constants.compiler import SpecialAttributes
42
+ from reflex.constants.state import FRONTEND_EVENT_STATE
40
43
  from reflex.event import (
41
44
  EventCallback,
42
45
  EventChain,
@@ -46,8 +49,8 @@ from reflex.event import (
46
49
  EventVar,
47
50
  call_event_fn,
48
51
  call_event_handler,
49
- empty_event,
50
52
  get_handler_args,
53
+ no_args_event_spec,
51
54
  )
52
55
  from reflex.style import Style, format_as_emotion
53
56
  from reflex.utils import format, imports, types
@@ -59,7 +62,15 @@ from reflex.utils.imports import (
59
62
  parse_imports,
60
63
  )
61
64
  from reflex.vars import VarData
62
- from reflex.vars.base import LiteralVar, Var
65
+ from reflex.vars.base import (
66
+ CachedVarOperation,
67
+ LiteralVar,
68
+ Var,
69
+ cached_property_no_lock,
70
+ )
71
+ from reflex.vars.function import ArgsFunctionOperation, FunctionStringVar
72
+ from reflex.vars.number import ternary_operation
73
+ from reflex.vars.object import ObjectVar
63
74
  from reflex.vars.sequence import LiteralArrayVar
64
75
 
65
76
 
@@ -147,7 +158,6 @@ class ComponentNamespace(SimpleNamespace):
147
158
  def __hash__(self) -> int:
148
159
  """Get the hash of the namespace.
149
160
 
150
-
151
161
  Returns:
152
162
  The hash of the namespace.
153
163
  """
@@ -219,7 +229,7 @@ class Component(BaseComponent, ABC):
219
229
  _rename_props: Dict[str, str] = {}
220
230
 
221
231
  # custom attribute
222
- custom_attrs: Dict[str, Union[Var, str]] = {}
232
+ custom_attrs: Dict[str, Union[Var, Any]] = {}
223
233
 
224
234
  # When to memoize this component and its children.
225
235
  _memoization_mode: MemoizationMode = MemoizationMode()
@@ -471,6 +481,7 @@ class Component(BaseComponent, ABC):
471
481
  kwargs["event_triggers"][key] = self._create_event_chain(
472
482
  value=value, # type: ignore
473
483
  args_spec=component_specific_triggers[key],
484
+ key=key,
474
485
  )
475
486
 
476
487
  # Remove any keys that were added as events.
@@ -523,7 +534,7 @@ class Component(BaseComponent, ABC):
523
534
 
524
535
  def _create_event_chain(
525
536
  self,
526
- args_spec: Any,
537
+ args_spec: types.ArgsSpec | Sequence[types.ArgsSpec],
527
538
  value: Union[
528
539
  Var,
529
540
  EventHandler,
@@ -531,12 +542,14 @@ class Component(BaseComponent, ABC):
531
542
  List[Union[EventHandler, EventSpec, EventVar]],
532
543
  Callable,
533
544
  ],
545
+ key: Optional[str] = None,
534
546
  ) -> Union[EventChain, Var]:
535
547
  """Create an event chain from a variety of input types.
536
548
 
537
549
  Args:
538
550
  args_spec: The args_spec of the event trigger being bound.
539
551
  value: The value to create the event chain from.
552
+ key: The key of the event trigger being bound.
540
553
 
541
554
  Returns:
542
555
  The event chain.
@@ -551,7 +564,7 @@ class Component(BaseComponent, ABC):
551
564
  elif isinstance(value, EventVar):
552
565
  value = [value]
553
566
  elif issubclass(value._var_type, (EventChain, EventSpec)):
554
- return self._create_event_chain(args_spec, value.guess_type())
567
+ return self._create_event_chain(args_spec, value.guess_type(), key=key)
555
568
  else:
556
569
  raise ValueError(
557
570
  f"Invalid event chain: {str(value)} of type {value._var_type}"
@@ -570,10 +583,10 @@ class Component(BaseComponent, ABC):
570
583
  for v in value:
571
584
  if isinstance(v, (EventHandler, EventSpec)):
572
585
  # Call the event handler to get the event.
573
- events.append(call_event_handler(v, args_spec))
586
+ events.append(call_event_handler(v, args_spec, key=key))
574
587
  elif isinstance(v, Callable):
575
588
  # Call the lambda to get the event chain.
576
- result = call_event_fn(v, args_spec)
589
+ result = call_event_fn(v, args_spec, key=key)
577
590
  if isinstance(result, Var):
578
591
  raise ValueError(
579
592
  f"Invalid event chain: {v}. Cannot use a Var-returning "
@@ -587,10 +600,10 @@ class Component(BaseComponent, ABC):
587
600
 
588
601
  # If the input is a callable, create an event chain.
589
602
  elif isinstance(value, Callable):
590
- result = call_event_fn(value, args_spec)
603
+ result = call_event_fn(value, args_spec, key=key)
591
604
  if isinstance(result, Var):
592
605
  # Recursively call this function if the lambda returned an EventChain Var.
593
- return self._create_event_chain(args_spec, result)
606
+ return self._create_event_chain(args_spec, result, key=key)
594
607
  events = [*result]
595
608
 
596
609
  # Otherwise, raise an error.
@@ -617,29 +630,31 @@ class Component(BaseComponent, ABC):
617
630
  event_actions={},
618
631
  )
619
632
 
620
- def get_event_triggers(self) -> Dict[str, Any]:
633
+ def get_event_triggers(
634
+ self,
635
+ ) -> Dict[str, types.ArgsSpec | Sequence[types.ArgsSpec]]:
621
636
  """Get the event triggers for the component.
622
637
 
623
638
  Returns:
624
639
  The event triggers.
625
640
 
626
641
  """
627
- default_triggers = {
628
- EventTriggers.ON_FOCUS: empty_event,
629
- EventTriggers.ON_BLUR: empty_event,
630
- EventTriggers.ON_CLICK: empty_event,
631
- EventTriggers.ON_CONTEXT_MENU: empty_event,
632
- EventTriggers.ON_DOUBLE_CLICK: empty_event,
633
- EventTriggers.ON_MOUSE_DOWN: empty_event,
634
- EventTriggers.ON_MOUSE_ENTER: empty_event,
635
- EventTriggers.ON_MOUSE_LEAVE: empty_event,
636
- EventTriggers.ON_MOUSE_MOVE: empty_event,
637
- EventTriggers.ON_MOUSE_OUT: empty_event,
638
- EventTriggers.ON_MOUSE_OVER: empty_event,
639
- EventTriggers.ON_MOUSE_UP: empty_event,
640
- EventTriggers.ON_SCROLL: empty_event,
641
- EventTriggers.ON_MOUNT: empty_event,
642
- EventTriggers.ON_UNMOUNT: empty_event,
642
+ default_triggers: Dict[str, types.ArgsSpec | Sequence[types.ArgsSpec]] = {
643
+ EventTriggers.ON_FOCUS: no_args_event_spec,
644
+ EventTriggers.ON_BLUR: no_args_event_spec,
645
+ EventTriggers.ON_CLICK: no_args_event_spec,
646
+ EventTriggers.ON_CONTEXT_MENU: no_args_event_spec,
647
+ EventTriggers.ON_DOUBLE_CLICK: no_args_event_spec,
648
+ EventTriggers.ON_MOUSE_DOWN: no_args_event_spec,
649
+ EventTriggers.ON_MOUSE_ENTER: no_args_event_spec,
650
+ EventTriggers.ON_MOUSE_LEAVE: no_args_event_spec,
651
+ EventTriggers.ON_MOUSE_MOVE: no_args_event_spec,
652
+ EventTriggers.ON_MOUSE_OUT: no_args_event_spec,
653
+ EventTriggers.ON_MOUSE_OVER: no_args_event_spec,
654
+ EventTriggers.ON_MOUSE_UP: no_args_event_spec,
655
+ EventTriggers.ON_SCROLL: no_args_event_spec,
656
+ EventTriggers.ON_MOUNT: no_args_event_spec,
657
+ EventTriggers.ON_UNMOUNT: no_args_event_spec,
643
658
  }
644
659
 
645
660
  # Look for component specific triggers,
@@ -650,7 +665,7 @@ class Component(BaseComponent, ABC):
650
665
  annotation = field.annotation
651
666
  if (metadata := getattr(annotation, "__metadata__", None)) is not None:
652
667
  args_spec = metadata[0]
653
- default_triggers[field.name] = args_spec or (empty_event) # type: ignore
668
+ default_triggers[field.name] = args_spec or (no_args_event_spec) # type: ignore
654
669
  return default_triggers
655
670
 
656
671
  def __repr__(self) -> str:
@@ -1130,7 +1145,10 @@ class Component(BaseComponent, ABC):
1130
1145
  if isinstance(event, EventCallback):
1131
1146
  continue
1132
1147
  if isinstance(event, EventSpec):
1133
- if event.handler.state_full_name:
1148
+ if (
1149
+ event.handler.state_full_name
1150
+ and event.handler.state_full_name != FRONTEND_EVENT_STATE
1151
+ ):
1134
1152
  return True
1135
1153
  else:
1136
1154
  if event._var_state:
@@ -1432,7 +1450,7 @@ class Component(BaseComponent, ABC):
1432
1450
  """
1433
1451
  ref = self.get_ref()
1434
1452
  if ref is not None:
1435
- return f"const {ref} = useRef(null); {str(Var(_js_expr=ref).as_ref())} = {ref};"
1453
+ return f"const {ref} = useRef(null); {str(Var(_js_expr=ref)._as_ref())} = {ref};"
1436
1454
 
1437
1455
  def _get_vars_hooks(self) -> dict[str, None]:
1438
1456
  """Get the hooks required by vars referenced in this component.
@@ -1711,8 +1729,9 @@ class CustomComponent(Component):
1711
1729
  value = self._create_event_chain(
1712
1730
  value=value,
1713
1731
  args_spec=event_triggers_in_component_declaration.get(
1714
- key, empty_event
1732
+ key, no_args_event_spec
1715
1733
  ),
1734
+ key=key,
1716
1735
  )
1717
1736
  self.props[format.to_camel_case(key)] = value
1718
1737
  continue
@@ -2345,3 +2364,203 @@ class MemoizationLeaf(Component):
2345
2364
 
2346
2365
 
2347
2366
  load_dynamic_serializer()
2367
+
2368
+
2369
+ class ComponentVar(Var[Component], python_types=BaseComponent):
2370
+ """A Var that represents a Component."""
2371
+
2372
+
2373
+ def empty_component() -> Component:
2374
+ """Create an empty component.
2375
+
2376
+ Returns:
2377
+ An empty component.
2378
+ """
2379
+ from reflex.components.base.bare import Bare
2380
+
2381
+ return Bare.create("")
2382
+
2383
+
2384
+ def render_dict_to_var(tag: dict | Component | str, imported_names: set[str]) -> Var:
2385
+ """Convert a render dict to a Var.
2386
+
2387
+ Args:
2388
+ tag: The render dict.
2389
+ imported_names: The names of the imported components.
2390
+
2391
+ Returns:
2392
+ The Var.
2393
+ """
2394
+ if not isinstance(tag, dict):
2395
+ if isinstance(tag, Component):
2396
+ return render_dict_to_var(tag.render(), imported_names)
2397
+ return Var.create(tag)
2398
+
2399
+ if "iterable" in tag:
2400
+ function_return = Var.create(
2401
+ [
2402
+ render_dict_to_var(child.render(), imported_names)
2403
+ for child in tag["children"]
2404
+ ]
2405
+ )
2406
+
2407
+ func = ArgsFunctionOperation.create(
2408
+ (tag["arg_var_name"], tag["index_var_name"]),
2409
+ function_return,
2410
+ )
2411
+
2412
+ return FunctionStringVar.create("Array.prototype.map.call").call(
2413
+ tag["iterable"]
2414
+ if not isinstance(tag["iterable"], ObjectVar)
2415
+ else tag["iterable"].items(),
2416
+ func,
2417
+ )
2418
+
2419
+ if tag["name"] == "match":
2420
+ element = tag["cond"]
2421
+
2422
+ conditionals = tag["default"]
2423
+
2424
+ for case in tag["match_cases"][::-1]:
2425
+ condition = case[0].to_string() == element.to_string()
2426
+ for pattern in case[1:-1]:
2427
+ condition = condition | (pattern.to_string() == element.to_string())
2428
+
2429
+ conditionals = ternary_operation(
2430
+ condition,
2431
+ case[-1],
2432
+ conditionals,
2433
+ )
2434
+
2435
+ return conditionals
2436
+
2437
+ if "cond" in tag:
2438
+ return ternary_operation(
2439
+ tag["cond"],
2440
+ render_dict_to_var(tag["true_value"], imported_names),
2441
+ render_dict_to_var(tag["false_value"], imported_names)
2442
+ if tag["false_value"] is not None
2443
+ else Var.create(None),
2444
+ )
2445
+
2446
+ props = {}
2447
+
2448
+ special_props = []
2449
+
2450
+ for prop_str in tag["props"]:
2451
+ if "=" not in prop_str:
2452
+ special_props.append(Var(prop_str).to(ObjectVar))
2453
+ continue
2454
+ prop = prop_str.index("=")
2455
+ key = prop_str[:prop]
2456
+ value = prop_str[prop + 2 : -1]
2457
+ props[key] = value
2458
+
2459
+ props = Var.create({Var.create(k): Var(v) for k, v in props.items()})
2460
+
2461
+ for prop in special_props:
2462
+ props = props.merge(prop)
2463
+
2464
+ contents = tag["contents"][1:-1] if tag["contents"] else None
2465
+
2466
+ raw_tag_name = tag.get("name")
2467
+ tag_name = Var(raw_tag_name or "Fragment")
2468
+
2469
+ tag_name = (
2470
+ Var.create(raw_tag_name)
2471
+ if raw_tag_name
2472
+ and raw_tag_name.split(".")[0] not in imported_names
2473
+ and raw_tag_name.lower() == raw_tag_name
2474
+ else tag_name
2475
+ )
2476
+
2477
+ return FunctionStringVar.create(
2478
+ "jsx",
2479
+ ).call(
2480
+ tag_name,
2481
+ props,
2482
+ *([Var(contents)] if contents is not None else []),
2483
+ *[render_dict_to_var(child, imported_names) for child in tag["children"]],
2484
+ )
2485
+
2486
+
2487
+ @dataclasses.dataclass(
2488
+ eq=False,
2489
+ frozen=True,
2490
+ )
2491
+ class LiteralComponentVar(CachedVarOperation, LiteralVar, ComponentVar):
2492
+ """A Var that represents a Component."""
2493
+
2494
+ _var_value: BaseComponent = dataclasses.field(default_factory=empty_component)
2495
+
2496
+ @cached_property_no_lock
2497
+ def _cached_var_name(self) -> str:
2498
+ """Get the name of the var.
2499
+
2500
+ Returns:
2501
+ The name of the var.
2502
+ """
2503
+ var_data = self._get_all_var_data()
2504
+ if var_data is not None:
2505
+ # flatten imports
2506
+ imported_names = {j.alias or j.name for i in var_data.imports for j in i[1]}
2507
+ else:
2508
+ imported_names = set()
2509
+ return str(render_dict_to_var(self._var_value.render(), imported_names))
2510
+
2511
+ @cached_property_no_lock
2512
+ def _cached_get_all_var_data(self) -> VarData | None:
2513
+ """Get the VarData for the var.
2514
+
2515
+ Returns:
2516
+ The VarData for the var.
2517
+ """
2518
+ return VarData.merge(
2519
+ VarData(
2520
+ imports={
2521
+ "@emotion/react": [
2522
+ ImportVar(tag="jsx"),
2523
+ ],
2524
+ }
2525
+ ),
2526
+ VarData(
2527
+ imports=self._var_value._get_all_imports(),
2528
+ ),
2529
+ VarData(
2530
+ imports={
2531
+ "react": [
2532
+ ImportVar(tag="Fragment"),
2533
+ ],
2534
+ }
2535
+ ),
2536
+ )
2537
+
2538
+ def __hash__(self) -> int:
2539
+ """Get the hash of the var.
2540
+
2541
+ Returns:
2542
+ The hash of the var.
2543
+ """
2544
+ return hash((self.__class__.__name__, self._js_expr))
2545
+
2546
+ @classmethod
2547
+ def create(
2548
+ cls,
2549
+ value: Component,
2550
+ _var_data: VarData | None = None,
2551
+ ):
2552
+ """Create a var from a value.
2553
+
2554
+ Args:
2555
+ value: The value of the var.
2556
+ _var_data: Additional hooks and imports associated with the Var.
2557
+
2558
+ Returns:
2559
+ The var.
2560
+ """
2561
+ return LiteralComponentVar(
2562
+ _js_expr="",
2563
+ _var_type=type(value),
2564
+ _var_data=_var_data,
2565
+ _var_value=value,
2566
+ )
@@ -110,7 +110,7 @@ class ConnectionToaster(Toaster):
110
110
 
111
111
  individual_hooks = [
112
112
  f"const toast_props = {str(LiteralVar.create(props))};",
113
- f"const [userDismissed, setUserDismissed] = useState(false);",
113
+ "const [userDismissed, setUserDismissed] = useState(false);",
114
114
  FunctionStringVar(
115
115
  "useEffect",
116
116
  _var_data=VarData(
@@ -10,7 +10,7 @@ from reflex.components.el.elements.typography import Div
10
10
  from reflex.components.lucide.icon import Icon
11
11
  from reflex.components.sonner.toast import Toaster, ToastProps
12
12
  from reflex.constants.compiler import CompileVars
13
- from reflex.event import EventType
13
+ from reflex.event import BASE_STATE, EventType
14
14
  from reflex.style import Style
15
15
  from reflex.utils.imports import ImportVar
16
16
  from reflex.vars import VarData
@@ -88,22 +88,22 @@ class ConnectionToaster(Toaster):
88
88
  id: Optional[Any] = None,
89
89
  class_name: Optional[Any] = None,
90
90
  autofocus: Optional[bool] = None,
91
- custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
92
- on_blur: Optional[EventType[[]]] = None,
93
- on_click: Optional[EventType[[]]] = None,
94
- on_context_menu: Optional[EventType[[]]] = None,
95
- on_double_click: Optional[EventType[[]]] = None,
96
- on_focus: Optional[EventType[[]]] = None,
97
- on_mount: Optional[EventType[[]]] = None,
98
- on_mouse_down: Optional[EventType[[]]] = None,
99
- on_mouse_enter: Optional[EventType[[]]] = None,
100
- on_mouse_leave: Optional[EventType[[]]] = None,
101
- on_mouse_move: Optional[EventType[[]]] = None,
102
- on_mouse_out: Optional[EventType[[]]] = None,
103
- on_mouse_over: Optional[EventType[[]]] = None,
104
- on_mouse_up: Optional[EventType[[]]] = None,
105
- on_scroll: Optional[EventType[[]]] = None,
106
- on_unmount: Optional[EventType[[]]] = None,
91
+ custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
92
+ on_blur: Optional[EventType[[], BASE_STATE]] = None,
93
+ on_click: Optional[EventType[[], BASE_STATE]] = None,
94
+ on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
95
+ on_double_click: Optional[EventType[[], BASE_STATE]] = None,
96
+ on_focus: Optional[EventType[[], BASE_STATE]] = None,
97
+ on_mount: Optional[EventType[[], BASE_STATE]] = None,
98
+ on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
99
+ on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
100
+ on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
101
+ on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
102
+ on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
103
+ on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
104
+ on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
105
+ on_scroll: Optional[EventType[[], BASE_STATE]] = None,
106
+ on_unmount: Optional[EventType[[], BASE_STATE]] = None,
107
107
  **props,
108
108
  ) -> "ConnectionToaster":
109
109
  """Create a connection toaster component.
@@ -148,22 +148,22 @@ class ConnectionBanner(Component):
148
148
  id: Optional[Any] = None,
149
149
  class_name: Optional[Any] = None,
150
150
  autofocus: Optional[bool] = None,
151
- custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
152
- on_blur: Optional[EventType[[]]] = None,
153
- on_click: Optional[EventType[[]]] = None,
154
- on_context_menu: Optional[EventType[[]]] = None,
155
- on_double_click: Optional[EventType[[]]] = None,
156
- on_focus: Optional[EventType[[]]] = None,
157
- on_mount: Optional[EventType[[]]] = None,
158
- on_mouse_down: Optional[EventType[[]]] = None,
159
- on_mouse_enter: Optional[EventType[[]]] = None,
160
- on_mouse_leave: Optional[EventType[[]]] = None,
161
- on_mouse_move: Optional[EventType[[]]] = None,
162
- on_mouse_out: Optional[EventType[[]]] = None,
163
- on_mouse_over: Optional[EventType[[]]] = None,
164
- on_mouse_up: Optional[EventType[[]]] = None,
165
- on_scroll: Optional[EventType[[]]] = None,
166
- on_unmount: Optional[EventType[[]]] = None,
151
+ custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
152
+ on_blur: Optional[EventType[[], BASE_STATE]] = None,
153
+ on_click: Optional[EventType[[], BASE_STATE]] = None,
154
+ on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
155
+ on_double_click: Optional[EventType[[], BASE_STATE]] = None,
156
+ on_focus: Optional[EventType[[], BASE_STATE]] = None,
157
+ on_mount: Optional[EventType[[], BASE_STATE]] = None,
158
+ on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
159
+ on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
160
+ on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
161
+ on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
162
+ on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
163
+ on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
164
+ on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
165
+ on_scroll: Optional[EventType[[], BASE_STATE]] = None,
166
+ on_unmount: Optional[EventType[[], BASE_STATE]] = None,
167
167
  **props,
168
168
  ) -> "ConnectionBanner":
169
169
  """Create a connection banner component.
@@ -187,22 +187,22 @@ class ConnectionModal(Component):
187
187
  id: Optional[Any] = None,
188
188
  class_name: Optional[Any] = None,
189
189
  autofocus: Optional[bool] = None,
190
- custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
191
- on_blur: Optional[EventType[[]]] = None,
192
- on_click: Optional[EventType[[]]] = None,
193
- on_context_menu: Optional[EventType[[]]] = None,
194
- on_double_click: Optional[EventType[[]]] = None,
195
- on_focus: Optional[EventType[[]]] = None,
196
- on_mount: Optional[EventType[[]]] = None,
197
- on_mouse_down: Optional[EventType[[]]] = None,
198
- on_mouse_enter: Optional[EventType[[]]] = None,
199
- on_mouse_leave: Optional[EventType[[]]] = None,
200
- on_mouse_move: Optional[EventType[[]]] = None,
201
- on_mouse_out: Optional[EventType[[]]] = None,
202
- on_mouse_over: Optional[EventType[[]]] = None,
203
- on_mouse_up: Optional[EventType[[]]] = None,
204
- on_scroll: Optional[EventType[[]]] = None,
205
- on_unmount: Optional[EventType[[]]] = None,
190
+ custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
191
+ on_blur: Optional[EventType[[], BASE_STATE]] = None,
192
+ on_click: Optional[EventType[[], BASE_STATE]] = None,
193
+ on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
194
+ on_double_click: Optional[EventType[[], BASE_STATE]] = None,
195
+ on_focus: Optional[EventType[[], BASE_STATE]] = None,
196
+ on_mount: Optional[EventType[[], BASE_STATE]] = None,
197
+ on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
198
+ on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
199
+ on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
200
+ on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
201
+ on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
202
+ on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
203
+ on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
204
+ on_scroll: Optional[EventType[[], BASE_STATE]] = None,
205
+ on_unmount: Optional[EventType[[], BASE_STATE]] = None,
206
206
  **props,
207
207
  ) -> "ConnectionModal":
208
208
  """Create a connection banner component.
@@ -227,22 +227,22 @@ class WifiOffPulse(Icon):
227
227
  id: Optional[Any] = None,
228
228
  class_name: Optional[Any] = None,
229
229
  autofocus: Optional[bool] = None,
230
- custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
231
- on_blur: Optional[EventType[[]]] = None,
232
- on_click: Optional[EventType[[]]] = None,
233
- on_context_menu: Optional[EventType[[]]] = None,
234
- on_double_click: Optional[EventType[[]]] = None,
235
- on_focus: Optional[EventType[[]]] = None,
236
- on_mount: Optional[EventType[[]]] = None,
237
- on_mouse_down: Optional[EventType[[]]] = None,
238
- on_mouse_enter: Optional[EventType[[]]] = None,
239
- on_mouse_leave: Optional[EventType[[]]] = None,
240
- on_mouse_move: Optional[EventType[[]]] = None,
241
- on_mouse_out: Optional[EventType[[]]] = None,
242
- on_mouse_over: Optional[EventType[[]]] = None,
243
- on_mouse_up: Optional[EventType[[]]] = None,
244
- on_scroll: Optional[EventType[[]]] = None,
245
- on_unmount: Optional[EventType[[]]] = None,
230
+ custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
231
+ on_blur: Optional[EventType[[], BASE_STATE]] = None,
232
+ on_click: Optional[EventType[[], BASE_STATE]] = None,
233
+ on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
234
+ on_double_click: Optional[EventType[[], BASE_STATE]] = None,
235
+ on_focus: Optional[EventType[[], BASE_STATE]] = None,
236
+ on_mount: Optional[EventType[[], BASE_STATE]] = None,
237
+ on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
238
+ on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
239
+ on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
240
+ on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
241
+ on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
242
+ on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
243
+ on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
244
+ on_scroll: Optional[EventType[[], BASE_STATE]] = None,
245
+ on_unmount: Optional[EventType[[], BASE_STATE]] = None,
246
246
  **props,
247
247
  ) -> "WifiOffPulse":
248
248
  """Create a wifi_off icon with an animated opacity pulse.
@@ -300,22 +300,22 @@ class ConnectionPulser(Div):
300
300
  id: Optional[Any] = None,
301
301
  class_name: Optional[Any] = None,
302
302
  autofocus: Optional[bool] = None,
303
- custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
304
- on_blur: Optional[EventType[[]]] = None,
305
- on_click: Optional[EventType[[]]] = None,
306
- on_context_menu: Optional[EventType[[]]] = None,
307
- on_double_click: Optional[EventType[[]]] = None,
308
- on_focus: Optional[EventType[[]]] = None,
309
- on_mount: Optional[EventType[[]]] = None,
310
- on_mouse_down: Optional[EventType[[]]] = None,
311
- on_mouse_enter: Optional[EventType[[]]] = None,
312
- on_mouse_leave: Optional[EventType[[]]] = None,
313
- on_mouse_move: Optional[EventType[[]]] = None,
314
- on_mouse_out: Optional[EventType[[]]] = None,
315
- on_mouse_over: Optional[EventType[[]]] = None,
316
- on_mouse_up: Optional[EventType[[]]] = None,
317
- on_scroll: Optional[EventType[[]]] = None,
318
- on_unmount: Optional[EventType[[]]] = None,
303
+ custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
304
+ on_blur: Optional[EventType[[], BASE_STATE]] = None,
305
+ on_click: Optional[EventType[[], BASE_STATE]] = None,
306
+ on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
307
+ on_double_click: Optional[EventType[[], BASE_STATE]] = None,
308
+ on_focus: Optional[EventType[[], BASE_STATE]] = None,
309
+ on_mount: Optional[EventType[[], BASE_STATE]] = None,
310
+ on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
311
+ on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
312
+ on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
313
+ on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
314
+ on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
315
+ on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
316
+ on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
317
+ on_scroll: Optional[EventType[[], BASE_STATE]] = None,
318
+ on_unmount: Optional[EventType[[], BASE_STATE]] = None,
319
319
  **props,
320
320
  ) -> "ConnectionPulser":
321
321
  """Create a connection pulser component.