@@ -449,8 +449,8 @@ def __call__(self, *args, **kwargs) -> EventSpec:
449449class EventChain (EventActionsMixin ):
450450 """Container for a chain of events that will be executed in order."""
451451
452- events : Sequence ["EventSpec | EventVar | EventCallback" ] = dataclasses . field (
453- default_factory = list
452+ events : Sequence ["EventSpec | EventVar | FunctionVar | EventCallback" ] = (
453+ dataclasses . field ( default_factory = list )
454454 )
455455
456456 args_spec : Callable | Sequence [Callable ] | None = dataclasses .field (default = None )
@@ -483,6 +483,8 @@ def create(
483483 if isinstance (value , Var ):
484484 if isinstance (value , EventChainVar ):
485485 return value
486+ if isinstance (value , FunctionVar ):
487+ return value
486488 if isinstance (value , EventVar ):
487489 value = [value ]
488490 elif safe_issubclass (value ._var_type , (EventChain , EventSpec )):
@@ -505,23 +507,26 @@ def create(
505507
506508 # If the input is a list of event handlers, create an event chain.
507509 if isinstance (value , list ):
508- events : list [EventSpec | EventVar ] = []
510+ events : list [EventSpec | EventVar | FunctionVar ] = []
509511 for v in value :
510512 if isinstance (v , (EventHandler , EventSpec )):
511513 # Call the event handler to get the event.
512514 events .append (call_event_handler (v , args_spec , key = key ))
515+ elif isinstance (v , (EventVar , FunctionVar )):
516+ events .append (v )
513517 elif isinstance (v , Callable ):
514518 # Call the lambda to get the event chain.
515519 result = call_event_fn (v , args_spec , key = key )
516520 if isinstance (result , Var ):
521+ if isinstance (result , (EventVar , FunctionVar )):
522+ events .append (result )
523+ continue
517524 msg = (
518525 f"Invalid event chain: { v } . Cannot use a Var-returning "
519526 "lambda inside an EventChain list."
520527 )
521528 raise ValueError (msg )
522529 events .extend (result )
523- elif isinstance (v , EventVar ):
524- events .append (v )
525530 else :
526531 msg = f"Invalid event: { v } "
527532 raise ValueError (msg )
@@ -2077,12 +2082,15 @@ def create(
20772082 sig = inspect .signature (arg_spec ) # pyright: ignore [reportArgumentType]
20782083 if sig .parameters :
20792084 arg_def = tuple (f"_{ p } " for p in sig .parameters )
2080- arg_def_expr = LiteralVar .create ([Var (_js_expr = arg ) for arg in arg_def ])
2085+ arg_vars = tuple (Var (_js_expr = arg ) for arg in arg_def )
2086+ arg_def_expr = LiteralVar .create (list (arg_vars ))
2087+ call_args = arg_vars
20812088 else :
20822089 # add a default argument for addEvents if none were specified in value.args_spec
20832090 # used to trigger the preventDefault() on the event.
20842091 arg_def = ("...args" ,)
20852092 arg_def_expr = Var (_js_expr = "args" )
2093+ call_args = (Var (_js_expr = "...args" ),)
20862094
20872095 if value .invocation is None :
20882096 invocation = FunctionStringVar .create (
@@ -2099,16 +2107,73 @@ def create(
20992107 msg = f"EventChain invocation must be a FunctionVar, got { invocation !s} of type { invocation ._var_type !s} ."
21002108 raise ValueError (msg )
21012109
2110+ has_function_var = any (isinstance (e , FunctionVar ) for e in value .events )
2111+
2112+ if not has_function_var :
2113+ return_expr = invocation .call (
2114+ LiteralVar .create ([LiteralVar .create (event ) for event in value .events ]),
2115+ arg_def_expr ,
2116+ value .event_actions ,
2117+ )
2118+ else :
2119+ statement_js : list [str ] = []
2120+ statement_var_data : list [VarData | None ] = []
2121+ queueable_group : list [EventSpec | EventVar | EventCallback ] = []
2122+
2123+ if value .event_actions .get ("preventDefault" ) or value .event_actions .get (
2124+ "stopPropagation"
2125+ ):
2126+ statement_js .append (
2127+ "const _reflex_dom_event = "
2128+ f"{ arg_def_expr } .filter((o) => o?.preventDefault !== undefined)[0];"
2129+ )
2130+ if value .event_actions .get ("preventDefault" ):
2131+ statement_js .append (
2132+ "if (_reflex_dom_event?.preventDefault) "
2133+ "{_reflex_dom_event.preventDefault();}"
2134+ )
2135+ if value .event_actions .get ("stopPropagation" ):
2136+ statement_js .append (
2137+ "if (_reflex_dom_event?.stopPropagation) "
2138+ "{_reflex_dom_event.stopPropagation();}"
2139+ )
2140+
2141+ def flush_queueable_group () -> None :
2142+ if not queueable_group :
2143+ return
2144+ queue_call = invocation .call (
2145+ LiteralVar .create ([
2146+ LiteralVar .create (event ) for event in queueable_group
2147+ ]),
2148+ arg_def_expr ,
2149+ {},
2150+ )
2151+ statement_js .append (f"{ queue_call !s} ;" )
2152+ statement_var_data .append (queue_call ._get_all_var_data ())
2153+ queueable_group .clear ()
2154+
2155+ for event in value .events :
2156+ if isinstance (event , FunctionVar ):
2157+ flush_queueable_group ()
2158+ function_call = event .call (* call_args )
2159+ statement_js .append (f"{ function_call !s} ;" )
2160+ statement_var_data .append (function_call ._get_all_var_data ())
2161+ else :
2162+ queueable_group .append (event )
2163+
2164+ flush_queueable_group ()
2165+
2166+ return_expr = Var (
2167+ _js_expr = f"{{{ '' .join (statement_js )} }}" ,
2168+ _var_data = VarData .merge (* statement_var_data ),
2169+ )
2170+
21022171 return cls (
21032172 _js_expr = "" ,
21042173 _var_type = EventChain ,
21052174 _var_data = _var_data ,
21062175 _args = FunctionArgs (arg_def ),
2107- _return_expr = invocation .call (
2108- LiteralVar .create ([LiteralVar .create (event ) for event in value .events ]),
2109- arg_def_expr ,
2110- value .event_actions ,
2111- ),
2176+ _return_expr = return_expr ,
21122177 _var_value = value ,
21132178 )
21142179
0 commit comments