11"""Window event listener component for Reflex."""
22
3+ from __future__ import annotations
4+
5+ from typing import Any , cast
6+
37import reflex as rx
48from reflex .components .base .fragment import Fragment
9+ from reflex .components .component import StatefulComponent , field
510from reflex .constants .compiler import Hooks
611from reflex .event import key_event , no_args_event_spec
712from reflex .vars .base import Var , VarData
@@ -61,6 +66,23 @@ class WindowEventListener(Fragment):
6166 on_popstate : rx .EventHandler [no_args_event_spec ]
6267 on_storage : rx .EventHandler [_on_storage_spec ]
6368
69+ hooks : list [str ] = field (default_factory = list , is_javascript_property = False )
70+
71+ @classmethod
72+ def create (cls , ** props ) -> WindowEventListener :
73+ """Create a WindowEventListener component.
74+
75+ Args:
76+ **props: The props to set on the component.
77+
78+ Returns:
79+ The created component.
80+ """
81+ real_component = cast ("WindowEventListener" , super ().create (** props ))
82+ hooks = StatefulComponent ._fix_event_triggers (real_component )
83+ real_component .hooks = hooks
84+ return real_component
85+
6486 def _exclude_props (self ) -> list [str ]:
6587 """Exclude event handler props from being passed to Fragment.
6688
@@ -69,31 +91,30 @@ def _exclude_props(self) -> list[str]:
6991 """
7092 return [* super ()._exclude_props (), * self .event_triggers .keys ()]
7193
72- def add_hooks (self ) -> list [str | Var [str ]]:
94+ def add_hooks (self ) -> list [str | Var [Any ]]:
7395 """Add hooks to register window event listeners.
7496
7597 Returns:
7698 The hooks to add to the component.
7799 """
78- hooks = []
100+ hooks : list [ str | Var [ Any ]] = [* self . hooks ]
79101
80102 for prop_name , event_trigger in self .event_triggers .items ():
81103 # Get JS event name: remove on_ prefix and underscores
82104 event_name = prop_name .removeprefix ("on_" ).replace ("_" , "" )
83105
84106 hook_expr = f"""
85- useEffect(() => {{
86- if (typeof window === 'undefined') return;
87-
88- window.addEventListener('{ event_name } ', { event_trigger } );
89- return () => window.removeEventListener('{ event_name } ', { event_trigger } );
90- }}, []);
107+ useEffect(() => {{
108+ if (typeof window === 'undefined') return;
109+ const fn = { Var . create ( event_trigger ) } ;
110+ window.addEventListener('{ event_name } ', fn );
111+ return () => window.removeEventListener('{ event_name } ', fn );
112+ }}, []);
91113 """
92114
93115 hooks .append (
94116 Var (
95117 hook_expr ,
96- _var_type = "str" ,
97118 _var_data = VarData (position = Hooks .HookPosition .POST_TRIGGER ),
98119 )
99120 )
0 commit comments