reflex 0.6.2.post1__py3-none-any.whl → 0.6.3__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 (178) hide show
  1. reflex/__init__.py +3 -2
  2. reflex/__init__.pyi +3 -1
  3. reflex/components/base/app_wrap.pyi +17 -37
  4. reflex/components/base/body.pyi +17 -37
  5. reflex/components/base/document.pyi +77 -177
  6. reflex/components/base/error_boundary.pyi +18 -38
  7. reflex/components/base/fragment.pyi +17 -37
  8. reflex/components/base/head.pyi +32 -72
  9. reflex/components/base/link.pyi +32 -72
  10. reflex/components/base/meta.pyi +62 -142
  11. reflex/components/base/script.py +4 -4
  12. reflex/components/base/script.pyi +20 -40
  13. reflex/components/component.py +30 -19
  14. reflex/components/core/banner.pyi +77 -177
  15. reflex/components/core/client_side_routing.pyi +32 -72
  16. reflex/components/core/clipboard.py +3 -3
  17. reflex/components/core/clipboard.pyi +18 -38
  18. reflex/components/core/debounce.py +2 -2
  19. reflex/components/core/debounce.pyi +18 -38
  20. reflex/components/core/html.pyi +17 -37
  21. reflex/components/core/upload.py +4 -5
  22. reflex/components/core/upload.pyi +65 -145
  23. reflex/components/datadisplay/code.pyi +32 -72
  24. reflex/components/datadisplay/dataeditor.py +13 -13
  25. reflex/components/datadisplay/dataeditor.pyi +33 -83
  26. reflex/components/dynamic.py +6 -7
  27. reflex/components/el/__init__.pyi +1 -0
  28. reflex/components/el/element.pyi +17 -37
  29. reflex/components/el/elements/base.pyi +17 -37
  30. reflex/components/el/elements/forms.py +29 -14
  31. reflex/components/el/elements/forms.pyi +222 -504
  32. reflex/components/el/elements/inline.pyi +422 -982
  33. reflex/components/el/elements/media.pyi +377 -877
  34. reflex/components/el/elements/metadata.pyi +92 -212
  35. reflex/components/el/elements/other.pyi +107 -247
  36. reflex/components/el/elements/scripts.pyi +47 -107
  37. reflex/components/el/elements/sectioning.pyi +227 -527
  38. reflex/components/el/elements/tables.pyi +152 -352
  39. reflex/components/el/elements/typography.pyi +227 -527
  40. reflex/components/gridjs/datatable.py +2 -2
  41. reflex/components/gridjs/datatable.pyi +32 -72
  42. reflex/components/lucide/icon.pyi +32 -72
  43. reflex/components/markdown/markdown.pyi +16 -36
  44. reflex/components/moment/moment.py +2 -2
  45. reflex/components/moment/moment.pyi +18 -38
  46. reflex/components/next/base.pyi +17 -37
  47. reflex/components/next/image.py +3 -3
  48. reflex/components/next/image.pyi +19 -39
  49. reflex/components/next/link.pyi +17 -37
  50. reflex/components/next/video.pyi +17 -37
  51. reflex/components/plotly/plotly.py +1 -1
  52. reflex/components/plotly/plotly.pyi +35 -87
  53. reflex/components/radix/primitives/accordion.py +14 -2
  54. reflex/components/radix/primitives/accordion.pyi +110 -250
  55. reflex/components/radix/primitives/base.pyi +32 -72
  56. reflex/components/radix/primitives/drawer.py +30 -12
  57. reflex/components/radix/primitives/drawer.pyi +159 -373
  58. reflex/components/radix/primitives/form.py +3 -3
  59. reflex/components/radix/primitives/form.pyi +158 -364
  60. reflex/components/radix/primitives/progress.pyi +77 -177
  61. reflex/components/radix/primitives/slider.py +17 -3
  62. reflex/components/radix/primitives/slider.pyi +81 -183
  63. reflex/components/radix/themes/base.pyi +107 -247
  64. reflex/components/radix/themes/color_mode.pyi +48 -117
  65. reflex/components/radix/themes/components/alert_dialog.py +5 -5
  66. reflex/components/radix/themes/components/alert_dialog.pyi +111 -259
  67. reflex/components/radix/themes/components/aspect_ratio.pyi +17 -37
  68. reflex/components/radix/themes/components/avatar.pyi +17 -37
  69. reflex/components/radix/themes/components/badge.pyi +17 -37
  70. reflex/components/radix/themes/components/button.pyi +17 -37
  71. reflex/components/radix/themes/components/callout.pyi +77 -177
  72. reflex/components/radix/themes/components/card.pyi +17 -37
  73. reflex/components/radix/themes/components/checkbox.py +3 -3
  74. reflex/components/radix/themes/components/checkbox.pyi +50 -110
  75. reflex/components/radix/themes/components/checkbox_cards.pyi +32 -72
  76. reflex/components/radix/themes/components/checkbox_group.pyi +32 -72
  77. reflex/components/radix/themes/components/context_menu.py +11 -11
  78. reflex/components/radix/themes/components/context_menu.pyi +132 -312
  79. reflex/components/radix/themes/components/data_list.pyi +62 -142
  80. reflex/components/radix/themes/components/dialog.py +7 -7
  81. reflex/components/radix/themes/components/dialog.pyi +114 -268
  82. reflex/components/radix/themes/components/dropdown_menu.py +13 -13
  83. reflex/components/radix/themes/components/dropdown_menu.pyi +134 -316
  84. reflex/components/radix/themes/components/hover_card.py +2 -2
  85. reflex/components/radix/themes/components/hover_card.pyi +64 -148
  86. reflex/components/radix/themes/components/icon_button.pyi +17 -37
  87. reflex/components/radix/themes/components/inset.pyi +17 -37
  88. reflex/components/radix/themes/components/popover.py +8 -8
  89. reflex/components/radix/themes/components/popover.pyi +69 -163
  90. reflex/components/radix/themes/components/progress.pyi +17 -37
  91. reflex/components/radix/themes/components/radio.pyi +17 -37
  92. reflex/components/radix/themes/components/radio_cards.py +2 -2
  93. reflex/components/radix/themes/components/radio_cards.pyi +33 -75
  94. reflex/components/radix/themes/components/radio_group.py +4 -4
  95. reflex/components/radix/themes/components/radio_group.pyi +63 -143
  96. reflex/components/radix/themes/components/scroll_area.pyi +17 -37
  97. reflex/components/radix/themes/components/segmented_control.py +14 -2
  98. reflex/components/radix/themes/components/segmented_control.pyi +35 -73
  99. reflex/components/radix/themes/components/select.py +6 -5
  100. reflex/components/radix/themes/components/select.pyi +146 -338
  101. reflex/components/radix/themes/components/separator.pyi +17 -37
  102. reflex/components/radix/themes/components/skeleton.pyi +17 -37
  103. reflex/components/radix/themes/components/slider.py +19 -3
  104. reflex/components/radix/themes/components/slider.pyi +23 -41
  105. reflex/components/radix/themes/components/spinner.pyi +17 -37
  106. reflex/components/radix/themes/components/switch.py +2 -2
  107. reflex/components/radix/themes/components/switch.pyi +18 -38
  108. reflex/components/radix/themes/components/table.pyi +107 -247
  109. reflex/components/radix/themes/components/tabs.py +2 -2
  110. reflex/components/radix/themes/components/tabs.pyi +79 -179
  111. reflex/components/radix/themes/components/text_area.py +0 -16
  112. reflex/components/radix/themes/components/text_area.pyi +20 -42
  113. reflex/components/radix/themes/components/text_field.py +6 -6
  114. reflex/components/radix/themes/components/text_field.pyi +53 -117
  115. reflex/components/radix/themes/components/tooltip.py +4 -4
  116. reflex/components/radix/themes/components/tooltip.pyi +20 -46
  117. reflex/components/radix/themes/layout/base.pyi +17 -37
  118. reflex/components/radix/themes/layout/box.pyi +17 -37
  119. reflex/components/radix/themes/layout/center.pyi +17 -37
  120. reflex/components/radix/themes/layout/container.pyi +17 -37
  121. reflex/components/radix/themes/layout/flex.pyi +17 -37
  122. reflex/components/radix/themes/layout/grid.pyi +17 -37
  123. reflex/components/radix/themes/layout/list.pyi +77 -177
  124. reflex/components/radix/themes/layout/section.pyi +17 -37
  125. reflex/components/radix/themes/layout/spacer.pyi +17 -37
  126. reflex/components/radix/themes/layout/stack.pyi +47 -107
  127. reflex/components/radix/themes/typography/blockquote.pyi +17 -37
  128. reflex/components/radix/themes/typography/code.pyi +17 -37
  129. reflex/components/radix/themes/typography/heading.pyi +17 -37
  130. reflex/components/radix/themes/typography/link.pyi +17 -37
  131. reflex/components/radix/themes/typography/text.pyi +107 -247
  132. reflex/components/react_player/audio.pyi +33 -69
  133. reflex/components/react_player/react_player.py +17 -17
  134. reflex/components/react_player/react_player.pyi +33 -69
  135. reflex/components/react_player/video.pyi +33 -69
  136. reflex/components/recharts/cartesian.py +216 -186
  137. reflex/components/recharts/cartesian.pyi +623 -832
  138. reflex/components/recharts/charts.py +68 -65
  139. reflex/components/recharts/charts.pyi +213 -433
  140. reflex/components/recharts/general.py +27 -21
  141. reflex/components/recharts/general.pyi +94 -189
  142. reflex/components/recharts/polar.py +135 -97
  143. reflex/components/recharts/polar.pyi +219 -229
  144. reflex/components/recharts/recharts.py +5 -1
  145. reflex/components/recharts/recharts.pyi +37 -73
  146. reflex/components/sonner/toast.py +1 -1
  147. reflex/components/sonner/toast.pyi +17 -37
  148. reflex/components/suneditor/editor.pyi +26 -52
  149. reflex/components/tags/iter_tag.py +2 -2
  150. reflex/config.py +16 -0
  151. reflex/constants/__init__.py +2 -0
  152. reflex/constants/compiler.py +25 -0
  153. reflex/constants/installer.py +17 -16
  154. reflex/constants/state.py +11 -0
  155. reflex/constants/style.py +1 -1
  156. reflex/event.py +337 -84
  157. reflex/experimental/layout.pyi +78 -180
  158. reflex/istate/dynamic.py +3 -0
  159. reflex/state.py +197 -118
  160. reflex/style.py +5 -0
  161. reflex/testing.py +8 -5
  162. reflex/utils/compat.py +1 -3
  163. reflex/utils/exceptions.py +8 -0
  164. reflex/utils/path_ops.py +2 -2
  165. reflex/utils/prerequisites.py +2 -2
  166. reflex/utils/pyi_generator.py +44 -4
  167. reflex/utils/registry.py +17 -3
  168. reflex/utils/telemetry.py +1 -3
  169. reflex/utils/types.py +60 -16
  170. reflex/vars/__init__.py +2 -0
  171. reflex/vars/base.py +127 -72
  172. reflex/vars/object.py +5 -1
  173. reflex/vars/sequence.py +15 -3
  174. {reflex-0.6.2.post1.dist-info → reflex-0.6.3.dist-info}/METADATA +3 -3
  175. {reflex-0.6.2.post1.dist-info → reflex-0.6.3.dist-info}/RECORD +178 -176
  176. {reflex-0.6.2.post1.dist-info → reflex-0.6.3.dist-info}/LICENSE +0 -0
  177. {reflex-0.6.2.post1.dist-info → reflex-0.6.3.dist-info}/WHEEL +0 -0
  178. {reflex-0.6.2.post1.dist-info → reflex-0.6.3.dist-info}/entry_points.txt +0 -0
reflex/event.py CHANGED
@@ -8,35 +8,42 @@ import sys
8
8
  import types
9
9
  import urllib.parse
10
10
  from base64 import b64encode
11
+ from functools import partial
11
12
  from typing import (
12
13
  Any,
13
14
  Callable,
14
15
  ClassVar,
15
16
  Dict,
17
+ Generic,
16
18
  List,
17
19
  Optional,
18
20
  Tuple,
19
21
  Type,
22
+ TypeVar,
20
23
  Union,
21
24
  get_type_hints,
25
+ overload,
22
26
  )
23
27
 
24
- from typing_extensions import get_args, get_origin
28
+ from typing_extensions import ParamSpec, get_args, get_origin
25
29
 
26
30
  from reflex import constants
27
- from reflex.utils import format
31
+ from reflex.utils import console, format
28
32
  from reflex.utils.exceptions import EventFnArgMismatch, EventHandlerArgMismatch
29
33
  from reflex.utils.types import ArgsSpec, GenericType
30
34
  from reflex.vars import VarData
31
35
  from reflex.vars.base import (
32
- CachedVarOperation,
33
36
  LiteralNoneVar,
34
37
  LiteralVar,
35
38
  ToOperation,
36
39
  Var,
37
- cached_property_no_lock,
38
40
  )
39
- from reflex.vars.function import ArgsFunctionOperation, FunctionStringVar, FunctionVar
41
+ from reflex.vars.function import (
42
+ ArgsFunctionOperation,
43
+ FunctionStringVar,
44
+ FunctionVar,
45
+ VarOperationCall,
46
+ )
40
47
  from reflex.vars.object import ObjectVar
41
48
 
42
49
  try:
@@ -389,33 +396,107 @@ class EventChain(EventActionsMixin):
389
396
 
390
397
  args_spec: Optional[Callable] = dataclasses.field(default=None)
391
398
 
399
+ invocation: Optional[Var] = dataclasses.field(default=None)
392
400
 
393
- # These chains can be used for their side effects when no other events are desired.
394
- stop_propagation = EventChain(events=[], args_spec=lambda: []).stop_propagation
395
- prevent_default = EventChain(events=[], args_spec=lambda: []).prevent_default
401
+
402
+ @dataclasses.dataclass(
403
+ init=True,
404
+ frozen=True,
405
+ )
406
+ class JavascriptHTMLInputElement:
407
+ """Interface for a Javascript HTMLInputElement https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement."""
408
+
409
+ value: str = ""
396
410
 
397
411
 
398
412
  @dataclasses.dataclass(
399
413
  init=True,
400
414
  frozen=True,
401
415
  )
402
- class Target:
403
- """A Javascript event target."""
416
+ class JavascriptInputEvent:
417
+ """Interface for a Javascript InputEvent https://developer.mozilla.org/en-US/docs/Web/API/InputEvent."""
404
418
 
405
- checked: bool = False
406
- value: Any = None
419
+ target: JavascriptHTMLInputElement = JavascriptHTMLInputElement()
407
420
 
408
421
 
409
422
  @dataclasses.dataclass(
410
423
  init=True,
411
424
  frozen=True,
412
425
  )
413
- class FrontendEvent:
414
- """A Javascript event."""
426
+ class JavasciptKeyboardEvent:
427
+ """Interface for a Javascript KeyboardEvent https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent."""
415
428
 
416
- target: Target = Target()
417
429
  key: str = ""
418
- value: Any = None
430
+
431
+
432
+ def input_event(e: Var[JavascriptInputEvent]) -> Tuple[Var[str]]:
433
+ """Get the value from an input event.
434
+
435
+ Args:
436
+ e: The input event.
437
+
438
+ Returns:
439
+ The value from the input event.
440
+ """
441
+ return (e.target.value,)
442
+
443
+
444
+ def key_event(e: Var[JavasciptKeyboardEvent]) -> Tuple[Var[str]]:
445
+ """Get the key from a keyboard event.
446
+
447
+ Args:
448
+ e: The keyboard event.
449
+
450
+ Returns:
451
+ The key from the keyboard event.
452
+ """
453
+ return (e.key,)
454
+
455
+
456
+ def empty_event() -> Tuple[()]:
457
+ """Empty event handler.
458
+
459
+ Returns:
460
+ An empty tuple.
461
+ """
462
+ return tuple() # type: ignore
463
+
464
+
465
+ # These chains can be used for their side effects when no other events are desired.
466
+ stop_propagation = EventChain(events=[], args_spec=empty_event).stop_propagation
467
+ prevent_default = EventChain(events=[], args_spec=empty_event).prevent_default
468
+
469
+
470
+ T = TypeVar("T")
471
+
472
+
473
+ def identity_event(event_type: Type[T]) -> Callable[[Var[T]], Tuple[Var[T]]]:
474
+ """A helper function that returns the input event as output.
475
+
476
+ Args:
477
+ event_type: The type of the event.
478
+
479
+ Returns:
480
+ A function that returns the input event as output.
481
+ """
482
+
483
+ def inner(ev: Var[T]) -> Tuple[Var[T]]:
484
+ return (ev,)
485
+
486
+ inner.__signature__ = inspect.signature(inner).replace( # type: ignore
487
+ parameters=[
488
+ inspect.Parameter(
489
+ "ev",
490
+ kind=inspect.Parameter.POSITIONAL_OR_KEYWORD,
491
+ annotation=Var[event_type],
492
+ )
493
+ ],
494
+ return_annotation=Tuple[Var[event_type]],
495
+ )
496
+ inner.__annotations__["ev"] = Var[event_type]
497
+ inner.__annotations__["return"] = Tuple[Var[event_type]]
498
+
499
+ return inner
419
500
 
420
501
 
421
502
  @dataclasses.dataclass(
@@ -946,6 +1027,29 @@ def unwrap_var_annotation(annotation: GenericType):
946
1027
  return annotation
947
1028
 
948
1029
 
1030
+ def resolve_annotation(annotations: dict[str, Any], arg_name: str):
1031
+ """Resolve the annotation for the given argument name.
1032
+
1033
+ Args:
1034
+ annotations: The annotations.
1035
+ arg_name: The argument name.
1036
+
1037
+ Returns:
1038
+ The resolved annotation.
1039
+ """
1040
+ annotation = annotations.get(arg_name)
1041
+ if annotation is None:
1042
+ console.deprecate(
1043
+ feature_name="Unannotated event handler arguments",
1044
+ reason="Provide type annotations for event handler arguments.",
1045
+ deprecation_version="0.6.3",
1046
+ removal_version="0.7.0",
1047
+ )
1048
+ # Allow arbitrary attribute access two levels deep until removed.
1049
+ return Dict[str, dict]
1050
+ return annotation
1051
+
1052
+
949
1053
  def parse_args_spec(arg_spec: ArgsSpec):
950
1054
  """Parse the args provided in the ArgsSpec of an event trigger.
951
1055
 
@@ -958,13 +1062,15 @@ def parse_args_spec(arg_spec: ArgsSpec):
958
1062
  spec = inspect.getfullargspec(arg_spec)
959
1063
  annotations = get_type_hints(arg_spec)
960
1064
 
961
- return arg_spec(
962
- *[
963
- Var(f"_{l_arg}").to(
964
- unwrap_var_annotation(annotations.get(l_arg, FrontendEvent))
965
- )
966
- for l_arg in spec.args
967
- ]
1065
+ return list(
1066
+ arg_spec(
1067
+ *[
1068
+ Var(f"_{l_arg}").to(
1069
+ unwrap_var_annotation(resolve_annotation(annotations, l_arg))
1070
+ )
1071
+ for l_arg in spec.args
1072
+ ]
1073
+ )
968
1074
  )
969
1075
 
970
1076
 
@@ -1157,7 +1263,7 @@ class EventVar(ObjectVar):
1157
1263
  frozen=True,
1158
1264
  **{"slots": True} if sys.version_info >= (3, 10) else {},
1159
1265
  )
1160
- class LiteralEventVar(CachedVarOperation, LiteralVar, EventVar):
1266
+ class LiteralEventVar(VarOperationCall, LiteralVar, EventVar):
1161
1267
  """A literal event var."""
1162
1268
 
1163
1269
  _var_value: EventSpec = dataclasses.field(default=None) # type: ignore
@@ -1170,35 +1276,6 @@ class LiteralEventVar(CachedVarOperation, LiteralVar, EventVar):
1170
1276
  """
1171
1277
  return hash((self.__class__.__name__, self._js_expr))
1172
1278
 
1173
- @cached_property_no_lock
1174
- def _cached_var_name(self) -> str:
1175
- """The name of the var.
1176
-
1177
- Returns:
1178
- The name of the var.
1179
- """
1180
- return str(
1181
- FunctionStringVar("Event").call(
1182
- # event handler name
1183
- ".".join(
1184
- filter(
1185
- None,
1186
- format.get_event_handler_parts(self._var_value.handler),
1187
- )
1188
- ),
1189
- # event handler args
1190
- {str(name): value for name, value in self._var_value.args},
1191
- # event actions
1192
- self._var_value.event_actions,
1193
- # client handler name
1194
- *(
1195
- [self._var_value.client_handler_name]
1196
- if self._var_value.client_handler_name
1197
- else []
1198
- ),
1199
- )
1200
- )
1201
-
1202
1279
  @classmethod
1203
1280
  def create(
1204
1281
  cls,
@@ -1219,6 +1296,22 @@ class LiteralEventVar(CachedVarOperation, LiteralVar, EventVar):
1219
1296
  _var_type=EventSpec,
1220
1297
  _var_data=_var_data,
1221
1298
  _var_value=value,
1299
+ _func=FunctionStringVar("Event"),
1300
+ _args=(
1301
+ # event handler name
1302
+ ".".join(
1303
+ filter(
1304
+ None,
1305
+ format.get_event_handler_parts(value.handler),
1306
+ )
1307
+ ),
1308
+ # event handler args
1309
+ {str(name): value for name, value in value.args},
1310
+ # event actions
1311
+ value.event_actions,
1312
+ # client handler name
1313
+ *([value.client_handler_name] if value.client_handler_name else []),
1314
+ ),
1222
1315
  )
1223
1316
 
1224
1317
 
@@ -1231,7 +1324,10 @@ class EventChainVar(FunctionVar):
1231
1324
  frozen=True,
1232
1325
  **{"slots": True} if sys.version_info >= (3, 10) else {},
1233
1326
  )
1234
- class LiteralEventChainVar(CachedVarOperation, LiteralVar, EventChainVar):
1327
+ # Note: LiteralVar is second in the inheritance list allowing it act like a
1328
+ # CachedVarOperation (ArgsFunctionOperation) and get the _js_expr from the
1329
+ # _cached_var_name property.
1330
+ class LiteralEventChainVar(ArgsFunctionOperation, LiteralVar, EventChainVar):
1235
1331
  """A literal event chain var."""
1236
1332
 
1237
1333
  _var_value: EventChain = dataclasses.field(default=None) # type: ignore
@@ -1244,36 +1340,6 @@ class LiteralEventChainVar(CachedVarOperation, LiteralVar, EventChainVar):
1244
1340
  """
1245
1341
  return hash((self.__class__.__name__, self._js_expr))
1246
1342
 
1247
- @cached_property_no_lock
1248
- def _cached_var_name(self) -> str:
1249
- """The name of the var.
1250
-
1251
- Returns:
1252
- The name of the var.
1253
- """
1254
- sig = inspect.signature(self._var_value.args_spec) # type: ignore
1255
- if sig.parameters:
1256
- arg_def = tuple((f"_{p}" for p in sig.parameters))
1257
- arg_def_expr = LiteralVar.create([Var(_js_expr=arg) for arg in arg_def])
1258
- else:
1259
- # add a default argument for addEvents if none were specified in value.args_spec
1260
- # used to trigger the preventDefault() on the event.
1261
- arg_def = ("...args",)
1262
- arg_def_expr = Var(_js_expr="args")
1263
-
1264
- return str(
1265
- ArgsFunctionOperation.create(
1266
- arg_def,
1267
- FunctionStringVar.create("addEvents").call(
1268
- LiteralVar.create(
1269
- [LiteralVar.create(event) for event in self._var_value.events]
1270
- ),
1271
- arg_def_expr,
1272
- self._var_value.event_actions,
1273
- ),
1274
- )
1275
- )
1276
-
1277
1343
  @classmethod
1278
1344
  def create(
1279
1345
  cls,
@@ -1289,10 +1355,31 @@ class LiteralEventChainVar(CachedVarOperation, LiteralVar, EventChainVar):
1289
1355
  Returns:
1290
1356
  The created LiteralEventChainVar instance.
1291
1357
  """
1358
+ sig = inspect.signature(value.args_spec) # type: ignore
1359
+ if sig.parameters:
1360
+ arg_def = tuple((f"_{p}" for p in sig.parameters))
1361
+ arg_def_expr = LiteralVar.create([Var(_js_expr=arg) for arg in arg_def])
1362
+ else:
1363
+ # add a default argument for addEvents if none were specified in value.args_spec
1364
+ # used to trigger the preventDefault() on the event.
1365
+ arg_def = ("...args",)
1366
+ arg_def_expr = Var(_js_expr="args")
1367
+
1368
+ if value.invocation is None:
1369
+ invocation = FunctionStringVar.create("addEvents")
1370
+ else:
1371
+ invocation = value.invocation
1372
+
1292
1373
  return cls(
1293
1374
  _js_expr="",
1294
1375
  _var_type=EventChain,
1295
1376
  _var_data=_var_data,
1377
+ _args_names=arg_def,
1378
+ _return_expr=invocation.call(
1379
+ LiteralVar.create([LiteralVar.create(event) for event in value.events]),
1380
+ arg_def_expr,
1381
+ value.event_actions,
1382
+ ),
1296
1383
  _var_value=value,
1297
1384
  )
1298
1385
 
@@ -1321,3 +1408,169 @@ class ToEventChainVarOperation(ToOperation, EventChainVar):
1321
1408
  _original: Var = dataclasses.field(default_factory=lambda: LiteralNoneVar.create())
1322
1409
 
1323
1410
  _default_var_type: ClassVar[Type] = EventChain
1411
+
1412
+
1413
+ G = ParamSpec("G")
1414
+
1415
+ IndividualEventType = Union[EventSpec, EventHandler, Callable[G, Any], Var[Any]]
1416
+
1417
+ EventType = Union[IndividualEventType[G], List[IndividualEventType[G]]]
1418
+
1419
+ P = ParamSpec("P")
1420
+ T = TypeVar("T")
1421
+ V = TypeVar("V")
1422
+ V2 = TypeVar("V2")
1423
+ V3 = TypeVar("V3")
1424
+ V4 = TypeVar("V4")
1425
+ V5 = TypeVar("V5")
1426
+
1427
+ if sys.version_info >= (3, 10):
1428
+ from typing import Concatenate
1429
+
1430
+ class EventCallback(Generic[P, T]):
1431
+ """A descriptor that wraps a function to be used as an event."""
1432
+
1433
+ def __init__(self, func: Callable[Concatenate[Any, P], T]):
1434
+ """Initialize the descriptor with the function to be wrapped.
1435
+
1436
+ Args:
1437
+ func: The function to be wrapped.
1438
+ """
1439
+ self.func = func
1440
+
1441
+ @overload
1442
+ def __get__(
1443
+ self: EventCallback[[V], T], instance: None, owner
1444
+ ) -> Callable[[Union[Var[V], V]], EventSpec]: ...
1445
+
1446
+ @overload
1447
+ def __get__(
1448
+ self: EventCallback[[V, V2], T], instance: None, owner
1449
+ ) -> Callable[[Union[Var[V], V], Union[Var[V2], V2]], EventSpec]: ...
1450
+
1451
+ @overload
1452
+ def __get__(
1453
+ self: EventCallback[[V, V2, V3], T], instance: None, owner
1454
+ ) -> Callable[
1455
+ [Union[Var[V], V], Union[Var[V2], V2], Union[Var[V3], V3]],
1456
+ EventSpec,
1457
+ ]: ...
1458
+
1459
+ @overload
1460
+ def __get__(
1461
+ self: EventCallback[[V, V2, V3, V4], T], instance: None, owner
1462
+ ) -> Callable[
1463
+ [
1464
+ Union[Var[V], V],
1465
+ Union[Var[V2], V2],
1466
+ Union[Var[V3], V3],
1467
+ Union[Var[V4], V4],
1468
+ ],
1469
+ EventSpec,
1470
+ ]: ...
1471
+
1472
+ @overload
1473
+ def __get__(
1474
+ self: EventCallback[[V, V2, V3, V4, V5], T], instance: None, owner
1475
+ ) -> Callable[
1476
+ [
1477
+ Union[Var[V], V],
1478
+ Union[Var[V2], V2],
1479
+ Union[Var[V3], V3],
1480
+ Union[Var[V4], V4],
1481
+ Union[Var[V5], V5],
1482
+ ],
1483
+ EventSpec,
1484
+ ]: ...
1485
+
1486
+ @overload
1487
+ def __get__(self, instance, owner) -> Callable[P, T]: ...
1488
+
1489
+ def __get__(self, instance, owner) -> Callable:
1490
+ """Get the function with the instance bound to it.
1491
+
1492
+ Args:
1493
+ instance: The instance to bind to the function.
1494
+ owner: The owner of the function.
1495
+
1496
+ Returns:
1497
+ The function with the instance bound to it
1498
+ """
1499
+ if instance is None:
1500
+ return self.func # type: ignore
1501
+
1502
+ return partial(self.func, instance) # type: ignore
1503
+
1504
+ def event_handler(func: Callable[Concatenate[Any, P], T]) -> EventCallback[P, T]:
1505
+ """Wrap a function to be used as an event.
1506
+
1507
+ Args:
1508
+ func: The function to wrap.
1509
+
1510
+ Returns:
1511
+ The wrapped function.
1512
+ """
1513
+ return func # type: ignore
1514
+ else:
1515
+
1516
+ def event_handler(func: Callable[P, T]) -> Callable[P, T]:
1517
+ """Wrap a function to be used as an event.
1518
+
1519
+ Args:
1520
+ func: The function to wrap.
1521
+
1522
+ Returns:
1523
+ The wrapped function.
1524
+ """
1525
+ return func
1526
+
1527
+
1528
+ class EventNamespace(types.SimpleNamespace):
1529
+ """A namespace for event related classes."""
1530
+
1531
+ Event = Event
1532
+ EventHandler = EventHandler
1533
+ EventSpec = EventSpec
1534
+ CallableEventSpec = CallableEventSpec
1535
+ EventChain = EventChain
1536
+ EventVar = EventVar
1537
+ LiteralEventVar = LiteralEventVar
1538
+ EventChainVar = EventChainVar
1539
+ LiteralEventChainVar = LiteralEventChainVar
1540
+ ToEventVarOperation = ToEventVarOperation
1541
+ ToEventChainVarOperation = ToEventChainVarOperation
1542
+ EventType = EventType
1543
+
1544
+ __call__ = staticmethod(event_handler)
1545
+ get_event = staticmethod(get_event)
1546
+ get_hydrate_event = staticmethod(get_hydrate_event)
1547
+ fix_events = staticmethod(fix_events)
1548
+ call_event_handler = staticmethod(call_event_handler)
1549
+ call_event_fn = staticmethod(call_event_fn)
1550
+ get_handler_args = staticmethod(get_handler_args)
1551
+ check_fn_match_arg_spec = staticmethod(check_fn_match_arg_spec)
1552
+ resolve_annotation = staticmethod(resolve_annotation)
1553
+ parse_args_spec = staticmethod(parse_args_spec)
1554
+ identity_event = staticmethod(identity_event)
1555
+ input_event = staticmethod(input_event)
1556
+ key_event = staticmethod(key_event)
1557
+ empty_event = staticmethod(empty_event)
1558
+ server_side = staticmethod(server_side)
1559
+ redirect = staticmethod(redirect)
1560
+ console_log = staticmethod(console_log)
1561
+ back = staticmethod(back)
1562
+ window_alert = staticmethod(window_alert)
1563
+ set_focus = staticmethod(set_focus)
1564
+ scroll_to = staticmethod(scroll_to)
1565
+ set_value = staticmethod(set_value)
1566
+ remove_cookie = staticmethod(remove_cookie)
1567
+ clear_local_storage = staticmethod(clear_local_storage)
1568
+ remove_local_storage = staticmethod(remove_local_storage)
1569
+ clear_session_storage = staticmethod(clear_session_storage)
1570
+ remove_session_storage = staticmethod(remove_session_storage)
1571
+ set_clipboard = staticmethod(set_clipboard)
1572
+ download = staticmethod(download)
1573
+ call_script = staticmethod(call_script)
1574
+
1575
+
1576
+ event = EventNamespace()