Ver Fonte

swap all use of get_event_triggers to rx.EventHandler props (#3458)

Thomas Brandého há 11 meses atrás
pai
commit
463f7829d4
93 ficheiros alterados com 623 adições e 1057 exclusões
  1. 1 8
      reflex/.templates/apps/demo/code/webui/components/loading_icon.py
  2. 10 15
      reflex/components/base/script.py
  3. 1 2
      reflex/components/base/script.pyi
  4. 3 13
      reflex/components/chakra/forms/checkbox.py
  5. 1 3
      reflex/components/chakra/forms/checkbox.pyi
  6. 12 16
      reflex/components/chakra/forms/editable.py
  7. 1 3
      reflex/components/chakra/forms/editable.pyi
  8. 17 17
      reflex/components/chakra/forms/input.py
  9. 2 3
      reflex/components/chakra/forms/input.pyi
  10. 3 12
      reflex/components/chakra/forms/numberinput.py
  11. 1 3
      reflex/components/chakra/forms/numberinput.pyi
  12. 8 14
      reflex/components/chakra/forms/pininput.py
  13. 2 3
      reflex/components/chakra/forms/pininput.pyi
  14. 4 12
      reflex/components/chakra/forms/radio.py
  15. 2 3
      reflex/components/chakra/forms/radio.pyi
  16. 9 13
      reflex/components/chakra/forms/rangeslider.py
  17. 2 3
      reflex/components/chakra/forms/rangeslider.pyi
  18. 4 12
      reflex/components/chakra/forms/select.py
  19. 2 3
      reflex/components/chakra/forms/select.pyi
  20. 9 13
      reflex/components/chakra/forms/slider.py
  21. 2 3
      reflex/components/chakra/forms/slider.pyi
  22. 3 13
      reflex/components/chakra/forms/switch.py
  23. 1 3
      reflex/components/chakra/forms/switch.pyi
  24. 14 16
      reflex/components/chakra/forms/textarea.py
  25. 1 3
      reflex/components/chakra/forms/textarea.pyi
  26. 3 12
      reflex/components/chakra/media/avatar.py
  27. 1 2
      reflex/components/chakra/media/avatar.pyi
  28. 6 11
      reflex/components/chakra/media/image.py
  29. 2 2
      reflex/components/chakra/media/image.pyi
  30. 11 14
      reflex/components/chakra/overlay/alertdialog.py
  31. 1 2
      reflex/components/chakra/overlay/alertdialog.pyi
  32. 11 14
      reflex/components/chakra/overlay/drawer.py
  33. 1 2
      reflex/components/chakra/overlay/drawer.pyi
  34. 6 11
      reflex/components/chakra/overlay/menu.py
  35. 2 2
      reflex/components/chakra/overlay/menu.pyi
  36. 12 13
      reflex/components/chakra/overlay/modal.py
  37. 2 2
      reflex/components/chakra/overlay/modal.pyi
  38. 5 12
      reflex/components/chakra/overlay/popover.py
  39. 1 2
      reflex/components/chakra/overlay/popover.pyi
  40. 6 13
      reflex/components/chakra/overlay/tooltip.py
  41. 1 2
      reflex/components/chakra/overlay/tooltip.pyi
  42. 4 11
      reflex/components/core/debounce.py
  43. 1 1
      reflex/components/core/debounce.pyi
  44. 5 13
      reflex/components/core/upload.py
  45. 2 3
      reflex/components/core/upload.pyi
  46. 37 53
      reflex/components/datadisplay/dataeditor.py
  47. 43 91
      reflex/components/datadisplay/dataeditor.pyi
  48. 33 49
      reflex/components/el/elements/forms.py
  49. 1 5
      reflex/components/el/elements/forms.pyi
  50. 5 12
      reflex/components/moment/moment.py
  51. 2 2
      reflex/components/moment/moment.pyi
  52. 6 11
      reflex/components/next/image.py
  53. 2 2
      reflex/components/next/image.pyi
  54. 5 12
      reflex/components/radix/primitives/accordion.py
  55. 2 2
      reflex/components/radix/primitives/accordion.pyi
  56. 17 27
      reflex/components/radix/primitives/drawer.py
  57. 2 4
      reflex/components/radix/primitives/drawer.pyi
  58. 4 12
      reflex/components/radix/primitives/form.py
  59. 2 3
      reflex/components/radix/primitives/form.pyi
  60. 6 11
      reflex/components/radix/primitives/slider.py
  61. 2 2
      reflex/components/radix/primitives/slider.pyi
  62. 12 24
      reflex/components/radix/themes/components/alert_dialog.py
  63. 2 4
      reflex/components/radix/themes/components/alert_dialog.pyi
  64. 6 22
      reflex/components/radix/themes/components/checkbox.py
  65. 2 4
      reflex/components/radix/themes/components/checkbox.pyi
  66. 28 38
      reflex/components/radix/themes/components/context_menu.py
  67. 2 5
      reflex/components/radix/themes/components/context_menu.pyi
  68. 18 26
      reflex/components/radix/themes/components/dialog.py
  69. 2 4
      reflex/components/radix/themes/components/dialog.pyi
  70. 31 57
      reflex/components/radix/themes/components/dropdown_menu.py
  71. 2 7
      reflex/components/radix/themes/components/dropdown_menu.pyi
  72. 4 12
      reflex/components/radix/themes/components/hover_card.py
  73. 2 3
      reflex/components/radix/themes/components/hover_card.pyi
  74. 21 27
      reflex/components/radix/themes/components/popover.py
  75. 2 4
      reflex/components/radix/themes/components/popover.pyi
  76. 4 12
      reflex/components/radix/themes/components/radio_group.py
  77. 2 3
      reflex/components/radix/themes/components/radio_group.pyi
  78. 12 23
      reflex/components/radix/themes/components/select.py
  79. 1 4
      reflex/components/radix/themes/components/select.pyi
  80. 6 12
      reflex/components/radix/themes/components/slider.py
  81. 2 3
      reflex/components/radix/themes/components/slider.pyi
  82. 4 12
      reflex/components/radix/themes/components/switch.py
  83. 2 3
      reflex/components/radix/themes/components/switch.pyi
  84. 3 11
      reflex/components/radix/themes/components/tabs.py
  85. 1 2
      reflex/components/radix/themes/components/tabs.pyi
  86. 17 17
      reflex/components/radix/themes/components/text_area.py
  87. 2 3
      reflex/components/radix/themes/components/text_area.pyi
  88. 17 17
      reflex/components/radix/themes/components/text_field.py
  89. 2 3
      reflex/components/radix/themes/components/text_field.pyi
  90. 9 13
      reflex/components/radix/themes/components/tooltip.py
  91. 2 3
      reflex/components/radix/themes/components/tooltip.pyi
  92. 34 25
      reflex/components/suneditor/editor.py
  93. 2 3
      reflex/components/suneditor/editor.pyi

+ 1 - 8
reflex/.templates/apps/demo/code/webui/components/loading_icon.py

@@ -13,14 +13,7 @@ class LoadingIcon(rx.Component):
     stroke_width: rx.Var[str]
     speed: rx.Var[str]
     height: rx.Var[str]
-
-    def get_event_triggers(self) -> dict:
-        """Get the event triggers that pass the component's value to the handler.
-
-        Returns:
-            A dict mapping the event trigger to the var that is passed to the handler.
-        """
-        return {"on_change": lambda status: [status]}
+    on_change: rx.EventHandler[lambda status: [status]]
 
 
 loading_icon = LoadingIcon.create

+ 10 - 15
reflex/components/base/script.py

@@ -4,9 +4,8 @@ https://nextjs.org/docs/app/api-reference/components/script
 """
 from __future__ import annotations
 
-from typing import Any, Union
-
 from reflex.components.component import Component
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 
@@ -30,6 +29,15 @@ class Script(Component):
     # When the script will execute: afterInteractive | beforeInteractive | lazyOnload
     strategy: Var[str] = "afterInteractive"  # type: ignore
 
+    # Triggered when the script is loading
+    on_load: EventHandler[lambda: []]
+
+    # Triggered when the script has loaded
+    on_ready: EventHandler[lambda: []]
+
+    # Triggered when the script has errored
+    on_error: EventHandler[lambda: []]
+
     @classmethod
     def create(cls, *children, **props) -> Component:
         """Create an inline or user-defined script.
@@ -58,18 +66,5 @@ class Script(Component):
             raise ValueError("Must provide inline script or `src` prop.")
         return super().create(*children, **props)
 
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]:
-        """Get the event triggers for the component.
-
-        Returns:
-            The event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            "on_load": lambda: [],
-            "on_ready": lambda: [],
-            "on_error": lambda: [],
-        }
-
 
 script = Script.create

+ 1 - 2
reflex/components/base/script.pyi

@@ -7,8 +7,8 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Union
 from reflex.components.component import Component
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 class Script(Component):
@@ -112,6 +112,5 @@ class Script(Component):
             ValueError: when neither children nor `src` are specified.
         """
         ...
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]: ...
 
 script = Script.create

+ 3 - 13
reflex/components/chakra/forms/checkbox.py

@@ -1,14 +1,12 @@
 """A checkbox component."""
 from __future__ import annotations
 
-from typing import Any, Union
-
 from reflex.components.chakra import (
     ChakraComponent,
     LiteralColorScheme,
     LiteralTagSize,
 )
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 
@@ -56,16 +54,8 @@ class Checkbox(ChakraComponent):
     # The spacing between the checkbox and its label text (0.5rem)
     spacing: Var[str]
 
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]:
-        """Get the event triggers that pass the component's value to the handler.
-
-        Returns:
-            A dict mapping the event trigger to the var that is passed to the handler.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CHANGE: lambda e0: [e0.target.checked],
-        }
+    # Fired when the checkbox is checked or unchecked
+    on_change: EventHandler[lambda e0: [e0.target.checked]]
 
 
 class CheckboxGroup(ChakraComponent):

+ 1 - 3
reflex/components/chakra/forms/checkbox.pyi

@@ -7,13 +7,11 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Union
 from reflex.components.chakra import ChakraComponent, LiteralColorScheme, LiteralTagSize
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 class Checkbox(ChakraComponent):
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 12 - 16
reflex/components/chakra/forms/editable.py

@@ -1,10 +1,8 @@
 """An editable component."""
 from __future__ import annotations
 
-from typing import Any, Union
-
 from reflex.components.chakra import ChakraComponent
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 
@@ -37,19 +35,17 @@ class Editable(ChakraComponent):
     # The initial value of the Editable in both edit and preview mode.
     default_value: Var[str]
 
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]:
-        """Get the event triggers that pass the component's value to the handler.
-
-        Returns:
-            A dict mapping the event trigger to the var that is passed to the handler.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CHANGE: lambda e0: [e0],
-            EventTriggers.ON_EDIT: lambda e0: [e0],
-            EventTriggers.ON_SUBMIT: lambda e0: [e0],
-            EventTriggers.ON_CANCEL: lambda e0: [e0],
-        }
+    # Fired when the Editable is changed.
+    on_change: EventHandler[lambda e0: [e0]]
+
+    # Fired when the Editable is in edit mode.
+    on_edit: EventHandler[lambda e0: [e0]]
+
+    # Fired when the Editable is submitted.
+    on_submit: EventHandler[lambda e0: [e0]]
+
+    # Fired when the Editable is canceled.
+    on_cancel: EventHandler[lambda e0: [e0]]
 
 
 class EditableInput(ChakraComponent):

+ 1 - 3
reflex/components/chakra/forms/editable.pyi

@@ -7,13 +7,11 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Union
 from reflex.components.chakra import ChakraComponent
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 class Editable(ChakraComponent):
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 17 - 17
reflex/components/chakra/forms/input.py

@@ -1,6 +1,5 @@
 """An input component."""
 
-from typing import Any, Dict
 
 from reflex.components.chakra import (
     ChakraComponent,
@@ -10,7 +9,8 @@ from reflex.components.chakra import (
 from reflex.components.component import Component
 from reflex.components.core.debounce import DebounceInput
 from reflex.components.literals import LiteralInputType
-from reflex.constants import EventTriggers, MemoizationMode
+from reflex.constants import MemoizationMode
+from reflex.event import EventHandler
 from reflex.utils.imports import ImportDict
 from reflex.vars import Var
 
@@ -59,6 +59,21 @@ class Input(ChakraComponent):
     # The name of the form field
     name: Var[str]
 
+    # Fired when the input value changes.
+    on_change: EventHandler[lambda e0: [e0.target.value]]
+
+    # Fired when the input is focused.
+    on_focus: EventHandler[lambda e0: [e0.target.value]]
+
+    # Fired when the input lose focus.
+    on_blur: EventHandler[lambda e0: [e0.target.value]]
+
+    # Fired when a key is pressed down.
+    on_key_down: EventHandler[lambda e0: [e0.key]]
+
+    # Fired when a key is released.
+    on_key_up: EventHandler[lambda e0: [e0.key]]
+
     def add_imports(self) -> ImportDict:
         """Add imports for the Input component.
 
@@ -67,21 +82,6 @@ class Input(ChakraComponent):
         """
         return {"/utils/state": "set_val"}
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the event triggers that pass the component's value to the handler.
-
-        Returns:
-            A dict mapping the event trigger to the var that is passed to the handler.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CHANGE: lambda e0: [e0.target.value],
-            EventTriggers.ON_FOCUS: lambda e0: [e0.target.value],
-            EventTriggers.ON_BLUR: lambda e0: [e0.target.value],
-            EventTriggers.ON_KEY_DOWN: lambda e0: [e0.key],
-            EventTriggers.ON_KEY_UP: lambda e0: [e0.key],
-        }
-
     @classmethod
     def create(cls, *children, **props) -> Component:
         """Create an Input component.

+ 2 - 3
reflex/components/chakra/forms/input.pyi

@@ -7,7 +7,6 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Dict
 from reflex.components.chakra import (
     ChakraComponent,
     LiteralButtonSize,
@@ -16,13 +15,13 @@ from reflex.components.chakra import (
 from reflex.components.component import Component
 from reflex.components.core.debounce import DebounceInput
 from reflex.components.literals import LiteralInputType
-from reflex.constants import EventTriggers, MemoizationMode
+from reflex.constants import MemoizationMode
+from reflex.event import EventHandler
 from reflex.utils.imports import ImportDict
 from reflex.vars import Var
 
 class Input(ChakraComponent):
     def add_imports(self) -> ImportDict: ...
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 3 - 12
reflex/components/chakra/forms/numberinput.py

@@ -1,7 +1,6 @@
 """A number input component."""
 
 from numbers import Number
-from typing import Any, Dict
 
 from reflex.components.chakra import (
     ChakraComponent,
@@ -9,7 +8,7 @@ from reflex.components.chakra import (
     LiteralInputVariant,
 )
 from reflex.components.component import Component
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 
@@ -75,16 +74,8 @@ class NumberInput(ChakraComponent):
     # The name of the form field
     name: Var[str]
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the event triggers that pass the component's value to the handler.
-
-        Returns:
-            A dict mapping the event trigger to the var that is passed to the handler.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CHANGE: lambda e0: [e0],
-        }
+    # Fired when the input value changes.
+    on_change: EventHandler[lambda e0: [e0]]
 
     @classmethod
     def create(cls, *children, **props) -> Component:

+ 1 - 3
reflex/components/chakra/forms/numberinput.pyi

@@ -8,18 +8,16 @@ from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
 from numbers import Number
-from typing import Any, Dict
 from reflex.components.chakra import (
     ChakraComponent,
     LiteralButtonSize,
     LiteralInputVariant,
 )
 from reflex.components.component import Component
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 class NumberInput(ChakraComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 8 - 14
reflex/components/chakra/forms/pininput.py

@@ -2,12 +2,12 @@
 
 from __future__ import annotations
 
-from typing import Any, Optional, Union
+from typing import Optional
 
 from reflex.components.chakra import ChakraComponent, LiteralInputVariant
 from reflex.components.component import Component
 from reflex.components.tags.tag import Tag
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.utils import format
 from reflex.utils.imports import ImportDict, merge_imports
 from reflex.vars import Var
@@ -63,6 +63,12 @@ class PinInput(ChakraComponent):
     # The name of the form field
     name: Var[str]
 
+    # Fired when the pin input is changed.
+    on_change: EventHandler[lambda e0: [e0]]
+
+    # Fired when the pin input is completed.
+    on_complete: EventHandler[lambda e0: [e0]]
+
     def _get_imports(self) -> ImportDict:
         """Include PinInputField explicitly because it may not be a child component at compile time.
 
@@ -76,18 +82,6 @@ class PinInput(ChakraComponent):
             range_var._var_data.imports if range_var._var_data is not None else {},
         )
 
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]:
-        """Get the event triggers that pass the component's value to the handler.
-
-        Returns:
-            A dict mapping the event trigger to the var that is passed to the handler.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CHANGE: lambda e0: [e0],
-            EventTriggers.ON_COMPLETE: lambda e0: [e0],
-        }
-
     def get_ref(self) -> str | None:
         """Override ref handling to handle array refs.
 

+ 2 - 3
reflex/components/chakra/forms/pininput.pyi

@@ -7,17 +7,16 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Optional, Union
+from typing import Optional
 from reflex.components.chakra import ChakraComponent, LiteralInputVariant
 from reflex.components.component import Component
 from reflex.components.tags.tag import Tag
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.utils import format
 from reflex.utils.imports import ImportDict, merge_imports
 from reflex.vars import Var
 
 class PinInput(ChakraComponent):
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]: ...
     def get_ref(self) -> str | None: ...
     @overload
     @classmethod

+ 4 - 12
reflex/components/chakra/forms/radio.py

@@ -1,13 +1,13 @@
 """A radio component."""
 
 
-from typing import Any, Dict, List, Union
+from typing import Any, List
 
 from reflex.components.chakra import ChakraComponent
 from reflex.components.chakra.typography.text import Text
 from reflex.components.component import Component
 from reflex.components.core.foreach import Foreach
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.utils.types import _issubclass
 from reflex.vars import Var
 
@@ -26,16 +26,8 @@ class RadioGroup(ChakraComponent):
     # The name of the form field
     name: Var[str]
 
-    def get_event_triggers(self) -> Dict[str, Union[Var, Any]]:
-        """Get the event triggers that pass the component's value to the handler.
-
-        Returns:
-            A dict mapping the event trigger to the var that is passed to the handler.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CHANGE: lambda e0: [e0],
-        }
+    # Fired when the radio group value changes.
+    on_change: EventHandler[lambda e0: [e0]]
 
     @classmethod
     def create(cls, *children, **props) -> Component:

+ 2 - 3
reflex/components/chakra/forms/radio.pyi

@@ -7,17 +7,16 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Dict, List, Union
+from typing import Any, List
 from reflex.components.chakra import ChakraComponent
 from reflex.components.chakra.typography.text import Text
 from reflex.components.component import Component
 from reflex.components.core.foreach import Foreach
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.utils.types import _issubclass
 from reflex.vars import Var
 
 class RadioGroup(ChakraComponent):
-    def get_event_triggers(self) -> Dict[str, Union[Var, Any]]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 9 - 13
reflex/components/chakra/forms/rangeslider.py

@@ -1,11 +1,11 @@
 """A range slider component."""
 from __future__ import annotations
 
-from typing import Any, List, Optional, Union
+from typing import List, Optional
 
 from reflex.components.chakra import ChakraComponent, LiteralChakraDirection
 from reflex.components.component import Component
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.utils import format
 from reflex.vars import Var
 
@@ -48,18 +48,14 @@ class RangeSlider(ChakraComponent):
     # The name of the form field
     name: Var[str]
 
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]:
-        """Get the event triggers that pass the component's value to the handler.
+    # Fired when the value changes.
+    on_change: EventHandler[lambda e0: [e0]]
 
-        Returns:
-            A dict mapping the event trigger to the var that is passed to the handler.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CHANGE: lambda e0: [e0],
-            EventTriggers.ON_CHANGE_END: lambda e0: [e0],
-            EventTriggers.ON_CHANGE_START: lambda e0: [e0],
-        }
+    # Fired when the value starts changing.
+    on_change_start: EventHandler[lambda e0: [e0]]
+
+    # Fired when the value stops changing.
+    on_change_end: EventHandler[lambda e0: [e0]]
 
     def get_ref(self):
         """Get the ref of the component.

+ 2 - 3
reflex/components/chakra/forms/rangeslider.pyi

@@ -7,15 +7,14 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, List, Optional, Union
+from typing import List, Optional
 from reflex.components.chakra import ChakraComponent, LiteralChakraDirection
 from reflex.components.component import Component
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.utils import format
 from reflex.vars import Var
 
 class RangeSlider(ChakraComponent):
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]: ...
     def get_ref(self): ...
     @overload
     @classmethod

+ 4 - 12
reflex/components/chakra/forms/select.py

@@ -1,12 +1,12 @@
 """A select component."""
 
-from typing import Any, Dict, List, Union
+from typing import Any, List
 
 from reflex.components.chakra import ChakraComponent, LiteralInputVariant
 from reflex.components.chakra.typography.text import Text
 from reflex.components.component import Component
 from reflex.components.core.foreach import Foreach
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.utils.types import _issubclass
 from reflex.vars import Var
 
@@ -49,16 +49,8 @@ class Select(ChakraComponent):
     # The name of the form field
     name: Var[str]
 
-    def get_event_triggers(self) -> Dict[str, Union[Var, Any]]:
-        """Get the event triggers that pass the component's value to the handler.
-
-        Returns:
-            A dict mapping the event trigger to the var that is passed to the handler.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CHANGE: lambda e0: [e0.target.value],
-        }
+    # Fired when the value changes.
+    on_change: EventHandler[lambda e0: [e0.target.value]]
 
     @classmethod
     def create(cls, *children, **props) -> Component:

+ 2 - 3
reflex/components/chakra/forms/select.pyi

@@ -7,17 +7,16 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Dict, List, Union
+from typing import Any, List
 from reflex.components.chakra import ChakraComponent, LiteralInputVariant
 from reflex.components.chakra.typography.text import Text
 from reflex.components.component import Component
 from reflex.components.core.foreach import Foreach
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.utils.types import _issubclass
 from reflex.vars import Var
 
 class Select(ChakraComponent):
-    def get_event_triggers(self) -> Dict[str, Union[Var, Any]]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 9 - 13
reflex/components/chakra/forms/slider.py

@@ -1,11 +1,11 @@
 """A slider component."""
 from __future__ import annotations
 
-from typing import Any, Literal, Union
+from typing import Literal
 
 from reflex.components.chakra import ChakraComponent, LiteralChakraDirection
 from reflex.components.component import Component
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 LiteralLayout = Literal["horizontal", "vertical"]
@@ -70,18 +70,14 @@ class Slider(ChakraComponent):
     # The name of the form field
     name: Var[str]
 
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]:
-        """Get the event triggers that pass the component's value to the handler.
+    # Fired when the value changes.
+    on_change: EventHandler[lambda e0: [e0]]
 
-        Returns:
-            A dict mapping the event trigger to the var that is passed to the handler.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CHANGE: lambda e0: [e0],
-            EventTriggers.ON_CHANGE_END: lambda e0: [e0],
-            EventTriggers.ON_CHANGE_START: lambda e0: [e0],
-        }  # type: ignore
+    # Fired when the value starts changing.
+    on_change_start: EventHandler[lambda e0: [e0]]
+
+    # Fired when the value stops changing.
+    on_change_end: EventHandler[lambda e0: [e0]]
 
     @classmethod
     def create(cls, *children, **props) -> Component:

+ 2 - 3
reflex/components/chakra/forms/slider.pyi

@@ -7,16 +7,15 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Literal, Union
+from typing import Literal
 from reflex.components.chakra import ChakraComponent, LiteralChakraDirection
 from reflex.components.component import Component
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 LiteralLayout = Literal["horizontal", "vertical"]
 
 class Slider(ChakraComponent):
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 3 - 13
reflex/components/chakra/forms/switch.py

@@ -1,10 +1,8 @@
 """A switch component."""
 from __future__ import annotations
 
-from typing import Any, Union
-
 from reflex.components.chakra import ChakraComponent, LiteralColorScheme
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 
@@ -46,13 +44,5 @@ class Switch(ChakraComponent):
     # The color scheme of the switch (e.g. "blue", "green", "red", etc.)
     color_scheme: Var[LiteralColorScheme]
 
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]:
-        """Get the event triggers that pass the component's value to the handler.
-
-        Returns:
-            A dict mapping the event trigger to the var that is passed to the handler.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CHANGE: lambda e0: [e0.target.checked],
-        }
+    # Fired when the switch value changes
+    on_change: EventHandler[lambda e0: [e0.target.checked]]

+ 1 - 3
reflex/components/chakra/forms/switch.pyi

@@ -7,13 +7,11 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Union
 from reflex.components.chakra import ChakraComponent, LiteralColorScheme
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 class Switch(ChakraComponent):
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 14 - 16
reflex/components/chakra/forms/textarea.py

@@ -1,12 +1,10 @@
 """A textarea component."""
 from __future__ import annotations
 
-from typing import Any, Union
-
 from reflex.components.chakra import ChakraComponent, LiteralInputVariant
 from reflex.components.component import Component
 from reflex.components.core.debounce import DebounceInput
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 
@@ -48,20 +46,20 @@ class TextArea(ChakraComponent):
     # The name of the form field
     name: Var[str]
 
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]:
-        """Get the event triggers that pass the component's value to the handler.
+    # Fired when the value changes.
+    on_change: EventHandler[lambda e0: [e0.target.value]]
 
-        Returns:
-            A dict mapping the event trigger to the var that is passed to the handler.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CHANGE: lambda e0: [e0.target.value],
-            EventTriggers.ON_FOCUS: lambda e0: [e0.target.value],
-            EventTriggers.ON_BLUR: lambda e0: [e0.target.value],
-            EventTriggers.ON_KEY_DOWN: lambda e0: [e0.key],
-            EventTriggers.ON_KEY_UP: lambda e0: [e0.key],
-        }
+    # Fired when the textarea gets focus.
+    on_focus: EventHandler[lambda e0: [e0.target.value]]
+
+    # Fired when the textarea loses focus.
+    on_blur: EventHandler[lambda e0: [e0.target.value]]
+
+    # Fired when a key is pressed down.
+    on_key_down: EventHandler[lambda e0: [e0.key]]
+
+    # Fired when a key is released.
+    on_key_up: EventHandler[lambda e0: [e0.key]]
 
     @classmethod
     def create(cls, *children, **props) -> Component:

+ 1 - 3
reflex/components/chakra/forms/textarea.pyi

@@ -7,15 +7,13 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Union
 from reflex.components.chakra import ChakraComponent, LiteralInputVariant
 from reflex.components.component import Component
 from reflex.components.core.debounce import DebounceInput
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 class TextArea(ChakraComponent):
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 3 - 12
reflex/components/chakra/media/avatar.py

@@ -1,9 +1,8 @@
 """Avatar components."""
 from __future__ import annotations
 
-from typing import Any, Union
-
 from reflex.components.chakra import ChakraComponent, LiteralAvatarSize
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 
@@ -36,16 +35,8 @@ class Avatar(ChakraComponent):
     # "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "full"
     size: Var[LiteralAvatarSize]
 
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]:
-        """Get the event triggers for the component.
-
-        Returns:
-            The event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            "on_error": lambda: [],
-        }
+    # Fired when the image fails to load.
+    on_error: EventHandler[lambda: []]
 
 
 class AvatarBadge(ChakraComponent):

+ 1 - 2
reflex/components/chakra/media/avatar.pyi

@@ -7,12 +7,11 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Union
 from reflex.components.chakra import ChakraComponent, LiteralAvatarSize
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 class Avatar(ChakraComponent):
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 6 - 11
reflex/components/chakra/media/image.py

@@ -1,10 +1,11 @@
 """An image component."""
 from __future__ import annotations
 
-from typing import Any, Optional, Union
+from typing import Any, Optional
 
 from reflex.components.chakra import ChakraComponent, LiteralImageLoading
 from reflex.components.component import Component
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 
@@ -49,17 +50,11 @@ class Image(ChakraComponent):
     # Learn more _[here](https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images)_
     src_set: Var[str]
 
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]:
-        """Get the event triggers for the component.
+    # Fired when the image fails to load.
+    on_error: EventHandler[lambda: []]
 
-        Returns:
-            The event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            "on_error": lambda: [],
-            "on_load": lambda: [],
-        }
+    # Fired when the image is loaded.
+    on_load: EventHandler[lambda: []]
 
     @classmethod
     def create(cls, *children, **props) -> Component:

+ 2 - 2
reflex/components/chakra/media/image.pyi

@@ -7,13 +7,13 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Optional, Union
+from typing import Any, Optional
 from reflex.components.chakra import ChakraComponent, LiteralImageLoading
 from reflex.components.component import Component
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 class Image(ChakraComponent):
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 11 - 14
reflex/components/chakra/overlay/alertdialog.py

@@ -1,11 +1,10 @@
 """Alert dialog components."""
 from __future__ import annotations
 
-from typing import Any, Union
-
 from reflex.components.chakra import ChakraComponent, LiteralAlertDialogSize
 from reflex.components.chakra.media.icon import Icon
 from reflex.components.component import Component
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 
@@ -53,19 +52,17 @@ class AlertDialog(ChakraComponent):
     # If true, the siblings of the modal will have `aria-hidden` set to true so that screen readers can only see the modal. This is commonly known as making the other elements **inert**
     use_inert: Var[bool]
 
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]:
-        """Get the event triggers for the component.
+    # Fired when the modal is closing.
+    on_close: EventHandler[lambda: []]
 
-        Returns:
-            The event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            "on_close": lambda: [],
-            "on_close_complete": lambda: [],
-            "on_esc": lambda: [],
-            "on_overlay_click": lambda: [],
-        }
+    # Fired when the modal is closed and the exit animation is complete.
+    on_close_complete: EventHandler[lambda: []]
+
+    # Fired when the Esc key is pressed.
+    on_esc: EventHandler[lambda: []]
+
+    # Fired when the overlay is clicked.
+    on_overlay_click: EventHandler[lambda: []]
 
     @classmethod
     def create(

+ 1 - 2
reflex/components/chakra/overlay/alertdialog.pyi

@@ -7,14 +7,13 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Union
 from reflex.components.chakra import ChakraComponent, LiteralAlertDialogSize
 from reflex.components.chakra.media.icon import Icon
 from reflex.components.component import Component
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 class AlertDialog(ChakraComponent):
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 11 - 14
reflex/components/chakra/overlay/drawer.py

@@ -1,8 +1,6 @@
 """Container to stack elements with spacing."""
 from __future__ import annotations
 
-from typing import Any, Union
-
 from reflex.components.chakra import (
     ChakraComponent,
     LiteralColorScheme,
@@ -10,6 +8,7 @@ from reflex.components.chakra import (
 )
 from reflex.components.chakra.media.icon import Icon
 from reflex.components.component import Component
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 
@@ -69,19 +68,17 @@ class Drawer(ChakraComponent):
     # | "purple" | "pink" | "linkedin" | "facebook" | "messenger" | "whatsapp" | "twitter" | "telegram"
     color_scheme: Var[LiteralColorScheme]
 
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]:
-        """Get the event triggers for the component.
+    # Fired when the modal is closing.
+    on_close: EventHandler[lambda: []]
 
-        Returns:
-            The event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            "on_close": lambda: [],
-            "on_close_complete": lambda: [],
-            "on_esc": lambda: [],
-            "on_overlay_click": lambda: [],
-        }
+    # Fired when the modal is closed and the exit animation is complete.
+    on_close_complete: EventHandler[lambda: []]
+
+    # Fired when the Esc key is pressed.
+    on_esc: EventHandler[lambda: []]
+
+    # Fired when the overlay is clicked.
+    on_overlay_click: EventHandler[lambda: []]
 
     @classmethod
     def create(

+ 1 - 2
reflex/components/chakra/overlay/drawer.pyi

@@ -7,7 +7,6 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Union
 from reflex.components.chakra import (
     ChakraComponent,
     LiteralColorScheme,
@@ -15,10 +14,10 @@ from reflex.components.chakra import (
 )
 from reflex.components.chakra.media.icon import Icon
 from reflex.components.component import Component
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 class Drawer(ChakraComponent):
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 6 - 11
reflex/components/chakra/overlay/menu.py

@@ -1,7 +1,7 @@
 """Menu components."""
 from __future__ import annotations
 
-from typing import Any, List, Optional, Union
+from typing import List, Optional
 
 from reflex.components.chakra import (
     ChakraComponent,
@@ -11,6 +11,7 @@ from reflex.components.chakra import (
 )
 from reflex.components.chakra.forms.button import Button
 from reflex.components.component import Component
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 
@@ -67,17 +68,11 @@ class Menu(ChakraComponent):
     # The CSS positioning strategy to use. ("fixed" | "absolute")
     strategy: Var[LiteralMenuStrategy]
 
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]:
-        """Get the event triggers for the component.
+    # Fired when the menu is closed.
+    on_close: EventHandler[lambda: []]
 
-        Returns:
-            The event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            "on_close": lambda: [],
-            "on_open": lambda: [],
-        }
+    # Fired when the menu is opened.
+    on_open: EventHandler[lambda: []]
 
     @classmethod
     def create(

+ 2 - 2
reflex/components/chakra/overlay/menu.pyi

@@ -7,7 +7,7 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, List, Optional, Union
+from typing import List, Optional
 from reflex.components.chakra import (
     ChakraComponent,
     LiteralChakraDirection,
@@ -16,10 +16,10 @@ from reflex.components.chakra import (
 )
 from reflex.components.chakra.forms.button import Button
 from reflex.components.component import Component
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 class Menu(ChakraComponent):
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 12 - 13
reflex/components/chakra/overlay/modal.py

@@ -1,11 +1,12 @@
 """Modal components."""
 from __future__ import annotations
 
-from typing import Any, Literal, Optional, Union
+from typing import Literal, Optional, Union
 
 from reflex.components.chakra import ChakraComponent
 from reflex.components.chakra.media import Icon
 from reflex.components.component import Component
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 ModalSizes = Literal["xs", "sm", "md", "lg", "xl", "full"]
@@ -55,19 +56,17 @@ class Modal(ChakraComponent):
     # A11y: If true, the siblings of the modal will have `aria-hidden` set to true so that screen readers can only see the modal. This is commonly known as making the other elements **inert**
     use_inert: Var[bool]
 
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]:
-        """Get the event triggers for the component.
+    # Fired when the modal is closing.
+    on_close: EventHandler[lambda: []]
 
-        Returns:
-            The event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            "on_close": lambda: [],
-            "on_close_complete": lambda: [],
-            "on_esc": lambda: [],
-            "on_overlay_click": lambda: [],
-        }
+    # Fired when the modal is closed and the exit animation is complete.
+    on_close_complete: EventHandler[lambda: []]
+
+    # Fired when the Esc key is pressed.
+    on_esc: EventHandler[lambda: []]
+
+    # Fired when the overlay is clicked.
+    on_overlay_click: EventHandler[lambda: []]
 
     @classmethod
     def create(

+ 2 - 2
reflex/components/chakra/overlay/modal.pyi

@@ -7,16 +7,16 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Literal, Optional, Union
+from typing import Literal, Optional, Union
 from reflex.components.chakra import ChakraComponent
 from reflex.components.chakra.media import Icon
 from reflex.components.component import Component
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 ModalSizes = Literal["xs", "sm", "md", "lg", "xl", "full"]
 
 class Modal(ChakraComponent):
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 5 - 12
reflex/components/chakra/overlay/popover.py

@@ -1,8 +1,6 @@
 """Popover components."""
 from __future__ import annotations
 
-from typing import Any, Union
-
 from reflex.components.chakra import (
     ChakraComponent,
     LiteralChakraDirection,
@@ -10,6 +8,7 @@ from reflex.components.chakra import (
     LiteralPopOverTrigger,
 )
 from reflex.components.component import Component
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 
@@ -81,17 +80,11 @@ class Popover(ChakraComponent):
     # The interaction that triggers the popover. hover - means the popover will open when you hover with mouse or focus with keyboard on the popover trigger click - means the popover will open on click or press Enter to Space on keyboard ("click" | "hover")
     trigger: Var[LiteralPopOverTrigger]
 
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]:
-        """Get the event triggers for the component.
+    # Fired when the popover is closed.
+    on_close: EventHandler[lambda: []]
 
-        Returns:
-            The event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            "on_close": lambda: [],
-            "on_open": lambda: [],
-        }
+    # Fired when the popover is opened.
+    on_open: EventHandler[lambda: []]
 
     @classmethod
     def create(

+ 1 - 2
reflex/components/chakra/overlay/popover.pyi

@@ -7,7 +7,6 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Union
 from reflex.components.chakra import (
     ChakraComponent,
     LiteralChakraDirection,
@@ -15,10 +14,10 @@ from reflex.components.chakra import (
     LiteralPopOverTrigger,
 )
 from reflex.components.component import Component
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 class Popover(ChakraComponent):
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 6 - 13
reflex/components/chakra/overlay/tooltip.py

@@ -1,9 +1,8 @@
 """Tooltip components."""
 from __future__ import annotations
 
-from typing import Any, Union
-
 from reflex.components.chakra import ChakraComponent, LiteralChakraDirection
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 
@@ -63,14 +62,8 @@ class Tooltip(ChakraComponent):
     # If true, the tooltip will wrap its children in a `<span/>` with `tabIndex=0`
     should_wrap_children: Var[bool]
 
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]:
-        """Get the event triggers for the component.
-
-        Returns:
-            The event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            "on_close": lambda: [],
-            "on_open": lambda: [],
-        }
+    # Fired when the tooltip is closing.
+    on_close: EventHandler[lambda: []]
+
+    # Fired when the tooltip is opened.
+    on_open: EventHandler[lambda: []]

+ 1 - 2
reflex/components/chakra/overlay/tooltip.pyi

@@ -7,12 +7,11 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Union
 from reflex.components.chakra import ChakraComponent, LiteralChakraDirection
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 class Tooltip(ChakraComponent):
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 4 - 11
reflex/components/core/debounce.py

@@ -6,6 +6,7 @@ from typing import Any, Type, Union
 
 from reflex.components.component import Component
 from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var, VarData
 
 DEFAULT_DEBOUNCE_TIMEOUT = 300
@@ -43,6 +44,9 @@ class DebounceInput(Component):
     # The element to wrap
     element: Var[Type[Component]]
 
+    # Fired when the input value changes
+    on_change: EventHandler[lambda e0: [e0.value]]
+
     @classmethod
     def create(cls, *children: Component, **props: Any) -> Component:
         """Create a DebounceInput component.
@@ -125,17 +129,6 @@ class DebounceInput(Component):
         component._rename_props = child._rename_props
         return component
 
-    def get_event_triggers(self) -> dict[str, Any]:
-        """Get the event triggers that pass the component's value to the handler.
-
-        Returns:
-            A dict mapping the event trigger to the var that is passed to the handler.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CHANGE: lambda e0: [e0.value],
-        }
-
     def _render(self):
         return super()._render().remove_props("ref")
 

+ 1 - 1
reflex/components/core/debounce.pyi

@@ -10,6 +10,7 @@ from reflex.style import Style
 from typing import Any, Type, Union
 from reflex.components.component import Component
 from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var, VarData
 
 DEFAULT_DEBOUNCE_TIMEOUT = 300
@@ -105,6 +106,5 @@ class DebounceInput(Component):
             ValueError: if the child element does not have an on_change handler.
         """
         ...
-    def get_event_triggers(self) -> dict[str, Any]: ...
 
 debounce_input = DebounceInput.create

+ 5 - 13
reflex/components/core/upload.py

@@ -4,9 +4,8 @@ from __future__ import annotations
 
 import os
 from pathlib import Path
-from typing import Any, Callable, ClassVar, Dict, List, Optional, Union
+from typing import Callable, ClassVar, Dict, List, Optional
 
-from reflex import constants
 from reflex.components.component import Component, ComponentNamespace, MemoizationLeaf
 from reflex.components.el.elements.forms import Input
 from reflex.components.radix.themes.layout.box import Box
@@ -14,6 +13,7 @@ from reflex.constants import Dirs
 from reflex.event import (
     CallableEventSpec,
     EventChain,
+    EventHandler,
     EventSpec,
     call_event_fn,
     call_script,
@@ -214,6 +214,9 @@ class Upload(MemoizationLeaf):
     # Marked True when any Upload component is created.
     is_used: ClassVar[bool] = False
 
+    # Fired when files are dropped.
+    on_drop: EventHandler[_on_drop_spec]
+
     @classmethod
     def create(cls, *children, **props) -> Component:
         """Create an upload component.
@@ -278,17 +281,6 @@ class Upload(MemoizationLeaf):
             **upload_props,
         )
 
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]:
-        """Get the event triggers that pass the component's value to the handler.
-
-        Returns:
-            A dict mapping the event trigger to the var that is passed to the handler.
-        """
-        return {
-            **super().get_event_triggers(),
-            constants.EventTriggers.ON_DROP: _on_drop_spec,
-        }
-
     @classmethod
     def _update_arg_tuple_for_on_drop(cls, arg_value: tuple[Var, Var]):
         """Helper to update caller-provided EventSpec args for direct use with on_drop.

+ 2 - 3
reflex/components/core/upload.pyi

@@ -9,8 +9,7 @@ from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
 import os
 from pathlib import Path
-from typing import Any, Callable, ClassVar, Dict, List, Optional, Union
-from reflex import constants
+from typing import Callable, ClassVar, Dict, List, Optional
 from reflex.components.component import Component, ComponentNamespace, MemoizationLeaf
 from reflex.components.el.elements.forms import Input
 from reflex.components.radix.themes.layout.box import Box
@@ -18,6 +17,7 @@ from reflex.constants import Dirs
 from reflex.event import (
     CallableEventSpec,
     EventChain,
+    EventHandler,
     EventSpec,
     call_event_fn,
     call_script,
@@ -218,7 +218,6 @@ class Upload(MemoizationLeaf):
             The upload component.
         """
         ...
-    def get_event_triggers(self) -> dict[str, Union[Var, Any]]: ...
 
 class StyledUpload(Upload):
     @overload

+ 37 - 53
reflex/components/datadisplay/dataeditor.py

@@ -104,6 +104,19 @@ class DataEditorTheme(Base):
     text_medium: Optional[str] = None
 
 
+def on_edit_spec(pos, data: dict[str, Any]):
+    """The on edit spec function.
+
+    Args:
+        pos: The position of the edit event.
+        data: The data of the edit event.
+
+    Returns:
+        The position and data.
+    """
+    return [pos, data]
+
+
 class DataEditor(NoSSRComponent):
     """The DataEditor Component."""
 
@@ -206,52 +219,52 @@ class DataEditor(NoSSRComponent):
     # global theme
     theme: Var[Union[DataEditorTheme, Dict]]
 
-    # Triggered when a cell is activated.
+    # Fired when a cell is activated.
     on_cell_activated: EventHandler[lambda pos: [pos]]
 
-    # Triggered when a cell is clicked.
+    # Fired when a cell is clicked.
     on_cell_clicked: EventHandler[lambda pos: [pos]]
 
-    # Triggered when a cell is right-clicked.
+    # Fired when a cell is right-clicked.
     on_cell_context_menu: EventHandler[lambda pos: [pos]]
 
-    # Triggered when a cell is edited.
-    on_cell_edited: EventHandler[lambda pos, data: [pos, data]]
+    # Fired when a cell is edited.
+    on_cell_edited: EventHandler[on_edit_spec]
 
-    # Triggered when a group header is clicked.
-    on_group_header_clicked: EventHandler[lambda pos, data: [pos, data]]
+    # Fired when a group header is clicked.
+    on_group_header_clicked: EventHandler[on_edit_spec]
 
-    # Triggered when a group header is right-clicked.
+    # Fired when a group header is right-clicked.
     on_group_header_context_menu: EventHandler[lambda grp_idx, data: [grp_idx, data]]
 
-    # Triggered when a group header is renamed.
+    # Fired when a group header is renamed.
     on_group_header_renamed: EventHandler[lambda idx, val: [idx, val]]
 
-    # Triggered when a header is clicked.
+    # Fired when a header is clicked.
     on_header_clicked: EventHandler[lambda pos: [pos]]
 
-    # Triggered when a header is right-clicked.
+    # Fired when a header is right-clicked.
     on_header_context_menu: EventHandler[lambda pos: [pos]]
 
-    # Triggered when a header menu is clicked.
+    # Fired when a header menu item is clicked.
     on_header_menu_click: EventHandler[lambda col, pos: [col, pos]]
 
-    # Triggered when an item is hovered.
+    # Fired when an item is hovered.
     on_item_hovered: EventHandler[lambda pos: [pos]]
 
-    # Triggered when a selection is deleted.
+    # Fired when a selection is deleted.
     on_delete: EventHandler[lambda selection: [selection]]
 
-    # Triggered when editing is finished.
+    # Fired when editing is finished.
     on_finished_editing: EventHandler[lambda new_value, movement: [new_value, movement]]
 
-    # Triggered when a row is appended.
+    # Fired when a row is appended.
     on_row_appended: EventHandler[lambda: []]
 
-    # Triggered when the selection is cleared.
+    # Fired when the selection is cleared.
     on_selection_cleared: EventHandler[lambda: []]
 
-    # Triggered when a column is resized.
+    # Fired when a column is resized.
     on_column_resize: EventHandler[lambda col, width: [col, width]]
 
     def add_imports(self) -> ImportDict:
@@ -378,42 +391,13 @@ class DataEditor(NoSSRComponent):
             )
         }
 
+    def get_event_triggers(self) -> dict[str, Any]:
+        """Remove the default event triggers from Component.
 
-# try:
-#     pass
-
-#     # def format_dataframe_values(df: DataFrame) -> list[list[Any]]:
-#     #     """Format dataframe values to a list of lists.
-
-#     #     Args:
-#     #         df: The dataframe to format.
-
-#     #     Returns:
-#     #         The dataframe as a list of lists.
-#     #     """
-#     # return [
-#     #     [str(d) if isinstance(d, (list, tuple)) else d for d in data]
-#     #     for data in list(df.values.tolist())
-#     # ]
-#     # ...
-
-#     # @serializer
-#     # def serialize_dataframe(df: DataFrame) -> dict:
-#     #     """Serialize a pandas dataframe.
-
-#     #     Args:
-#     #         df: The dataframe to serialize.
-
-#     #     Returns:
-#     #         The serialized dataframe.
-#     #     """
-#     # return {
-#     #     "columns": df.columns.tolist(),
-#     #     "data": format_dataframe_values(df),
-#     # }
-
-# except ImportError:
-#     pass
+        Returns:
+            An empty dictionary.
+        """
+        return {}
 
 
 @serializer

+ 43 - 91
reflex/components/datadisplay/dataeditor.pyi

@@ -80,6 +80,8 @@ class DataEditorTheme(Base):
     text_light: Optional[str]
     text_medium: Optional[str]
 
+def on_edit_spec(pos, data: dict[str, Any]): ...
+
 class DataEditor(NoSSRComponent):
     def add_imports(self) -> ImportDict: ...
     def add_hooks(self) -> list[str]: ...
@@ -131,105 +133,38 @@ class DataEditor(NoSSRComponent):
         theme: Optional[
             Union[Var[Union[DataEditorTheme, Dict]], Union[DataEditorTheme, Dict]]
         ] = None,
-        style: Optional[Style] = None,
-        key: Optional[Any] = None,
-        id: Optional[Any] = None,
-        class_name: Optional[Any] = None,
-        autofocus: Optional[bool] = None,
-        custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
-        on_blur: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
-        on_cell_activated: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
-        on_cell_clicked: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
-        on_cell_context_menu: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
-        on_cell_edited: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
-        on_click: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
-        on_column_resize: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
-        on_context_menu: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
-        on_delete: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
-        on_double_click: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
-        on_finished_editing: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
-        on_focus: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
-        on_group_header_clicked: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
+        on_cell_activated: Optional[EventHandler[lambda pos: [pos]]] = None,
+        on_cell_clicked: Optional[EventHandler[lambda pos: [pos]]] = None,
+        on_cell_context_menu: Optional[EventHandler[lambda pos: [pos]]] = None,
+        on_cell_edited: Optional[EventHandler[on_edit_spec]] = None,
+        on_group_header_clicked: Optional[EventHandler[on_edit_spec]] = None,
         on_group_header_context_menu: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
+            EventHandler[lambda grp_idx, data: [grp_idx, data]]
         ] = None,
         on_group_header_renamed: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
-        on_header_clicked: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
-        on_header_context_menu: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
+            EventHandler[lambda idx, val: [idx, val]]
         ] = None,
+        on_header_clicked: Optional[EventHandler[lambda pos: [pos]]] = None,
+        on_header_context_menu: Optional[EventHandler[lambda pos: [pos]]] = None,
         on_header_menu_click: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
-        on_item_hovered: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
-        on_mount: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
-        on_mouse_down: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
-        on_mouse_enter: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
-        on_mouse_leave: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
-        on_mouse_move: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
-        on_mouse_out: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
-        on_mouse_over: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
-        on_mouse_up: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
+            EventHandler[lambda col, pos: [col, pos]]
         ] = None,
-        on_row_appended: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
-        on_scroll: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
-        on_selection_cleared: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
+        on_item_hovered: Optional[EventHandler[lambda pos: [pos]]] = None,
+        on_delete: Optional[EventHandler[lambda selection: [selection]]] = None,
+        on_finished_editing: Optional[
+            EventHandler[lambda new_value, movement: [new_value, movement]]
         ] = None,
-        on_unmount: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
+        on_row_appended: Optional[EventHandler[lambda: []]] = None,
+        on_selection_cleared: Optional[EventHandler[lambda: []]] = None,
+        on_column_resize: Optional[
+            EventHandler[lambda col, width: [col, width]]
         ] = None,
+        style: Optional[Style] = None,
+        key: Optional[Any] = None,
+        id: Optional[Any] = None,
+        class_name: Optional[Any] = None,
+        autofocus: Optional[bool] = None,
+        custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
         **props
     ) -> "DataEditor":
         """Create the DataEditor component.
@@ -265,6 +200,22 @@ class DataEditor(NoSSRComponent):
             scroll_offset_x: Initial scroll offset on the horizontal axis.
             scroll_offset_y: Initial scroll offset on the vertical axis.
             theme: global theme
+            on_cell_activated: Fired when a cell is activated.
+            on_cell_clicked: Fired when a cell is clicked.
+            on_cell_context_menu: Fired when a cell is right-clicked.
+            on_cell_edited: Fired when a cell is edited.
+            on_group_header_clicked: Fired when a group header is clicked.
+            on_group_header_context_menu: Fired when a group header is right-clicked.
+            on_group_header_renamed: Fired when a group header is renamed.
+            on_header_clicked: Fired when a header is clicked.
+            on_header_context_menu: Fired when a header is right-clicked.
+            on_header_menu_click: Fired when a header menu item is clicked.
+            on_item_hovered: Fired when an item is hovered.
+            on_delete: Fired when a selection is deleted.
+            on_finished_editing: Fired when editing is finished.
+            on_row_appended: Fired when a row is appended.
+            on_selection_cleared: Fired when the selection is cleared.
+            on_column_resize: Fired when a column is resized.
             style: The style of the component.
             key: A unique key for the component.
             id: The id for the component.
@@ -280,6 +231,7 @@ class DataEditor(NoSSRComponent):
             The DataEditor component.&
         """
         ...
+    def get_event_triggers(self) -> dict[str, Any]: ...
 
 @serializer
 def serialize_dataeditortheme(theme: DataEditorTheme): ...

+ 33 - 49
reflex/components/el/elements/forms.py

@@ -10,7 +10,7 @@ from jinja2 import Environment
 from reflex.components.el.element import Element
 from reflex.components.tags.tag import Tag
 from reflex.constants import Dirs, EventTriggers
-from reflex.event import EventChain
+from reflex.event import EventChain, EventHandler
 from reflex.utils.format import format_event_chain
 from reflex.utils.imports import ImportDict
 from reflex.vars import BaseVar, Var
@@ -134,16 +134,8 @@ class Form(BaseHTML):
     # The name used to make this form's submit handler function unique.
     handle_submit_unique_name: Var[str]
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Event triggers for radix form root.
-
-        Returns:
-            The triggers for event supported by Root.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_SUBMIT: lambda e0: [FORM_DATA],
-        }
+    # Fired when the form is submitted
+    on_submit: EventHandler[lambda e0: [FORM_DATA]]
 
     @classmethod
     def create(cls, *children, **props):
@@ -352,20 +344,20 @@ class Input(BaseHTML):
     # Value of the input
     value: Var[Union[str, int, float]]
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the event triggers that pass the component's value to the handler.
+    # Fired when the input value changes
+    on_change: EventHandler[lambda e0: [e0.target.value]]
 
-        Returns:
-            A dict mapping the event trigger to the var that is passed to the handler.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CHANGE: lambda e0: [e0.target.value],
-            EventTriggers.ON_FOCUS: lambda e0: [e0.target.value],
-            EventTriggers.ON_BLUR: lambda e0: [e0.target.value],
-            EventTriggers.ON_KEY_DOWN: lambda e0: [e0.key],
-            EventTriggers.ON_KEY_UP: lambda e0: [e0.key],
-        }
+    # Fired when the input gains focus
+    on_focus: EventHandler[lambda e0: [e0.target.value]]
+
+    # Fired when the input loses focus
+    on_blur: EventHandler[lambda e0: [e0.target.value]]
+
+    # Fired when a key is pressed down
+    on_key_down: EventHandler[lambda e0: [e0.key]]
+
+    # Fired when a key is released
+    on_key_up: EventHandler[lambda e0: [e0.key]]
 
 
 class Label(BaseHTML):
@@ -503,16 +495,8 @@ class Select(BaseHTML):
     # Number of visible options in a drop-down list
     size: Var[Union[str, int, bool]]
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the event triggers that pass the component's value to the handler.
-
-        Returns:
-            A dict mapping the event trigger to the var that is passed to the handler.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CHANGE: lambda e0: [e0.target.value],
-        }
+    # Fired when the select value changes
+    on_change: EventHandler[lambda e0: [e0.target.value]]
 
 
 AUTO_HEIGHT_JS = """
@@ -601,6 +585,21 @@ class Textarea(BaseHTML):
     # How the text in the textarea is to be wrapped when submitting the form
     wrap: Var[Union[str, int, bool]]
 
+    # Fired when the input value changes
+    on_change: EventHandler[lambda e0: [e0.target.value]]
+
+    # Fired when the input gains focus
+    on_focus: EventHandler[lambda e0: [e0.target.value]]
+
+    # Fired when the input loses focus
+    on_blur: EventHandler[lambda e0: [e0.target.value]]
+
+    # Fired when a key is pressed down
+    on_key_down: EventHandler[lambda e0: [e0.key]]
+
+    # Fired when a key is released
+    on_key_up: EventHandler[lambda e0: [e0.key]]
+
     def _exclude_props(self) -> list[str]:
         return super()._exclude_props() + [
             "auto_height",
@@ -646,21 +645,6 @@ class Textarea(BaseHTML):
             )
         return tag
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the event triggers that pass the component's value to the handler.
-
-        Returns:
-            A dict mapping the event trigger to the var that is passed to the handler.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CHANGE: lambda e0: [e0.target.value],
-            EventTriggers.ON_FOCUS: lambda e0: [e0.target.value],
-            EventTriggers.ON_BLUR: lambda e0: [e0.target.value],
-            EventTriggers.ON_KEY_DOWN: lambda e0: [e0.key],
-            EventTriggers.ON_KEY_UP: lambda e0: [e0.key],
-        }
-
 
 button = Button.create
 fieldset = Fieldset.create

+ 1 - 5
reflex/components/el/elements/forms.pyi

@@ -13,7 +13,7 @@ from jinja2 import Environment
 from reflex.components.el.element import Element
 from reflex.components.tags.tag import Tag
 from reflex.constants import Dirs, EventTriggers
-from reflex.event import EventChain
+from reflex.event import EventChain, EventHandler
 from reflex.utils.format import format_event_chain
 from reflex.utils.imports import ImportDict
 from reflex.vars import BaseVar, Var
@@ -409,7 +409,6 @@ class Fieldset(Element):
         ...
 
 class Form(BaseHTML):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore
@@ -585,7 +584,6 @@ class Form(BaseHTML):
     def add_hooks(self) -> list[str]: ...
 
 class Input(BaseHTML):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore
@@ -1823,7 +1821,6 @@ class Progress(BaseHTML):
         ...
 
 class Select(BaseHTML):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore
@@ -1988,7 +1985,6 @@ AUTO_HEIGHT_JS = '\nconst autoHeightOnInput = (e, is_enabled) => {\n    if (is_e
 ENTER_KEY_SUBMIT_JS = "\nconst enterKeySubmitOnKeyDown = (e, is_enabled) => {\n    if (is_enabled && e.which === 13 && !e.shiftKey) {\n        e.preventDefault();\n        if (!e.repeat) {\n            if (e.target.form) {\n                e.target.form.requestSubmit();\n            }\n        }\n    }\n}\n"
 
 class Textarea(BaseHTML):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 5 - 12
reflex/components/moment/moment.py

@@ -1,9 +1,10 @@
 """Moment component for humanized date rendering."""
 
-from typing import Any, Dict, List, Optional
+from typing import List, Optional
 
 from reflex.base import Base
 from reflex.components.component import Component, NoSSRComponent
+from reflex.event import EventHandler
 from reflex.utils.imports import ImportDict
 from reflex.vars import Var
 
@@ -90,6 +91,9 @@ class Moment(NoSSRComponent):
     # Display the date in the given timezone.
     tz: Var[str]
 
+    # Fires when the date changes.
+    on_change: EventHandler[lambda date: [date]]
+
     def add_imports(self) -> ImportDict:
         """Add the imports for the Moment component.
 
@@ -100,17 +104,6 @@ class Moment(NoSSRComponent):
             return {"moment-timezone": ""}
         return {}
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the events triggers signatures for the component.
-
-        Returns:
-            The signatures of the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            "on_change": lambda date: [date],
-        }
-
     @classmethod
     def create(cls, *children, **props) -> Component:
         """Create a Moment component.

+ 2 - 2
reflex/components/moment/moment.pyi

@@ -7,9 +7,10 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Dict, List, Optional
+from typing import List, Optional
 from reflex.base import Base
 from reflex.components.component import Component, NoSSRComponent
+from reflex.event import EventHandler
 from reflex.utils.imports import ImportDict
 from reflex.vars import Var
 
@@ -26,7 +27,6 @@ class MomentDelta(Base):
 
 class Moment(NoSSRComponent):
     def add_imports(self) -> ImportDict: ...
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 6 - 11
reflex/components/next/image.py

@@ -1,7 +1,8 @@
 """Image component from next/image."""
 
-from typing import Any, Dict, Literal, Optional, Union
+from typing import Any, Literal, Optional, Union
 
+from reflex.event import EventHandler
 from reflex.utils import types
 from reflex.vars import Var
 
@@ -54,17 +55,11 @@ class Image(NextComponent):
     # A Data URL to be used as a placeholder image before the src image successfully loads. Only takes effect when combined with placeholder="blur".
     blurDataURL: Var[str]
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """The event triggers of the component.
+    # Fires when the image has loaded.
+    on_load: EventHandler[lambda: []]
 
-        Returns:
-            The dict describing the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            "on_load": lambda: [],
-            "on_error": lambda: [],
-        }
+    # Fires when the image has an error.
+    on_error: EventHandler[lambda: []]
 
     @classmethod
     def create(

+ 2 - 2
reflex/components/next/image.pyi

@@ -7,13 +7,13 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Dict, Literal, Optional, Union
+from typing import Any, Literal, Optional, Union
+from reflex.event import EventHandler
 from reflex.utils import types
 from reflex.vars import Var
 from .base import NextComponent
 
 class Image(NextComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 5 - 12
reflex/components/radix/primitives/accordion.py

@@ -2,7 +2,7 @@
 
 from __future__ import annotations
 
-from typing import Any, Dict, List, Literal, Optional, Union
+from typing import Any, List, Literal, Optional, Union
 
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.core.colors import color
@@ -10,6 +10,7 @@ from reflex.components.core.cond import cond
 from reflex.components.lucide.icon import Icon
 from reflex.components.radix.primitives.base import RadixPrimitiveComponent
 from reflex.components.radix.themes.base import LiteralAccentColor, LiteralRadius
+from reflex.event import EventHandler
 from reflex.style import Style
 from reflex.vars import Var, get_uuid_string_var
 
@@ -111,6 +112,9 @@ class AccordionRoot(AccordionComponent):
 
     _valid_children: List[str] = ["AccordionItem"]
 
+    # Fired when the opened the accordions changes.
+    on_value_change: EventHandler[lambda e0: [e0]]
+
     def _exclude_props(self) -> list[str]:
         return super()._exclude_props() + [
             "radius",
@@ -119,17 +123,6 @@ class AccordionRoot(AccordionComponent):
             "show_dividers",
         ]
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the events triggers signatures for the component.
-
-        Returns:
-            The signatures of the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            "on_value_change": lambda e0: [e0],
-        }
-
     def add_style(self):
         """Add style to the component.
 

+ 2 - 2
reflex/components/radix/primitives/accordion.pyi

@@ -7,13 +7,14 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Dict, List, Literal, Optional, Union
+from typing import Any, List, Literal, Optional, Union
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.core.colors import color
 from reflex.components.core.cond import cond
 from reflex.components.lucide.icon import Icon
 from reflex.components.radix.primitives.base import RadixPrimitiveComponent
 from reflex.components.radix.themes.base import LiteralAccentColor, LiteralRadius
+from reflex.event import EventHandler
 from reflex.style import Style
 from reflex.vars import Var, get_uuid_string_var
 
@@ -174,7 +175,6 @@ class AccordionComponent(RadixPrimitiveComponent):
         ...
 
 class AccordionRoot(AccordionComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     def add_style(self): ...
     @overload
     @classmethod

+ 17 - 27
reflex/components/radix/primitives/drawer.py

@@ -4,13 +4,13 @@
 # Style based on https://ui.shadcn.com/docs/components/drawer
 from __future__ import annotations
 
-from typing import Any, Dict, List, Literal, Optional, Union
+from typing import Any, List, Literal, Optional, Union
 
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.radix.primitives.base import RadixPrimitiveComponent
 from reflex.components.radix.themes.base import Theme
 from reflex.components.radix.themes.layout.flex import Flex
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 
@@ -59,16 +59,8 @@ class DrawerRoot(DrawerComponent):
     # When `True`, it prevents scroll restoration. Defaults to `True`.
     preventScrollRestoration: Var[bool]
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the event triggers that pass the component's value to the handler.
-
-        Returns:
-            A dict mapping the event trigger to the var that is passed to the handler.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_OPEN_CHANGE: lambda e0: [e0],
-        }
+    # Fires when the drawer is opened.
+    on_open_change: EventHandler[lambda e0: [e0]]
 
 
 class DrawerTrigger(DrawerComponent):
@@ -135,22 +127,20 @@ class DrawerContent(DrawerComponent):
         base_style.update(style)
         return {"css": base_style}
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the events triggers signatures for the component.
+    # Fired when the drawer content is opened.
+    on_open_auto_focus: EventHandler[lambda e0: [e0.target.value]]
 
-        Returns:
-            The signatures of the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            # DrawerContent is based on Radix DialogContent
-            # These are the same triggers as DialogContent
-            EventTriggers.ON_OPEN_AUTO_FOCUS: lambda e0: [e0.target.value],
-            EventTriggers.ON_CLOSE_AUTO_FOCUS: lambda e0: [e0.target.value],
-            EventTriggers.ON_ESCAPE_KEY_DOWN: lambda e0: [e0.target.value],
-            EventTriggers.ON_POINTER_DOWN_OUTSIDE: lambda e0: [e0.target.value],
-            EventTriggers.ON_INTERACT_OUTSIDE: lambda e0: [e0.target.value],
-        }
+    # Fired when the drawer content is closed.
+    on_close_auto_focus: EventHandler[lambda e0: [e0.target.value]]
+
+    # Fired when the escape key is pressed.
+    on_escape_key_down: EventHandler[lambda e0: [e0.target.value]]
+
+    # Fired when the pointer is down outside the drawer content.
+    on_pointer_down_outside: EventHandler[lambda e0: [e0.target.value]]
+
+    # Fired when interacting outside the drawer content.
+    on_interact_outside: EventHandler[lambda e0: [e0.target.value]]
 
     @classmethod
     def create(cls, *children, **props):

+ 2 - 4
reflex/components/radix/primitives/drawer.pyi

@@ -7,12 +7,12 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Dict, List, Literal, Optional, Union
+from typing import Any, List, Literal, Optional, Union
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.radix.primitives.base import RadixPrimitiveComponent
 from reflex.components.radix.themes.base import Theme
 from reflex.components.radix.themes.layout.flex import Flex
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 class DrawerComponent(RadixPrimitiveComponent):
@@ -96,7 +96,6 @@ class DrawerComponent(RadixPrimitiveComponent):
 LiteralDirectionType = Literal["top", "bottom", "left", "right"]
 
 class DrawerRoot(DrawerComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore
@@ -350,7 +349,6 @@ class DrawerPortal(DrawerComponent):
         ...
 
 class DrawerContent(DrawerComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 4 - 12
reflex/components/radix/primitives/form.py

@@ -2,12 +2,12 @@
 
 from __future__ import annotations
 
-from typing import Any, Dict, Literal
+from typing import Any, Literal
 
 from reflex.components.component import ComponentNamespace
 from reflex.components.el.elements.forms import Form as HTMLForm
 from reflex.components.radix.themes.components.text_field import TextFieldRoot
-from reflex.constants.event import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 from .base import RadixPrimitiveComponentWithClassName
@@ -26,16 +26,8 @@ class FormRoot(FormComponent, HTMLForm):
 
     alias = "RadixFormRoot"
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Event triggers for radix form root.
-
-        Returns:
-            The triggers for event supported by Root.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CLEAR_SERVER_ERRORS: lambda: [],
-        }
+    # Fired when the errors are cleared.
+    on_clear_server_errors: EventHandler[lambda: []]
 
     def add_style(self) -> dict[str, Any] | None:
         """Add style to the component.

+ 2 - 3
reflex/components/radix/primitives/form.pyi

@@ -7,11 +7,11 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Dict, Literal
+from typing import Any, Literal
 from reflex.components.component import ComponentNamespace
 from reflex.components.el.elements.forms import Form as HTMLForm
 from reflex.components.radix.themes.components.text_field import TextFieldRoot
-from reflex.constants.event import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 from .base import RadixPrimitiveComponentWithClassName
 
@@ -94,7 +94,6 @@ class FormComponent(RadixPrimitiveComponentWithClassName):
         ...
 
 class FormRoot(FormComponent, HTMLForm):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     def add_style(self) -> dict[str, Any] | None: ...
     @overload
     @classmethod

+ 6 - 11
reflex/components/radix/primitives/slider.py

@@ -2,10 +2,11 @@
 
 from __future__ import annotations
 
-from typing import Any, Dict, List, Literal
+from typing import Any, List, Literal
 
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.radix.primitives.base import RadixPrimitiveComponentWithClassName
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 LiteralSliderOrientation = Literal["horizontal", "vertical"]
@@ -46,17 +47,11 @@ class SliderRoot(SliderComponent):
 
     min_steps_between_thumbs: Var[int]
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Event triggers for radix slider primitive.
+    # Fired when the value of a thumb changes.
+    on_value_change: EventHandler[lambda e0: [e0]]
 
-        Returns:
-            The triggers for event supported by radix primitives.
-        """
-        return {
-            **super().get_event_triggers(),
-            "on_value_change": lambda e0: [e0],  # trigger for all change of a thumb
-            "on_value_commit": lambda e0: [e0],  # trigger when thumb is released
-        }
+    # Fired when a thumb is released.
+    on_value_commit: EventHandler[lambda e0: [e0]]
 
     def add_style(self) -> dict[str, Any] | None:
         """Add style to the component.

+ 2 - 2
reflex/components/radix/primitives/slider.pyi

@@ -7,9 +7,10 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Dict, List, Literal
+from typing import Any, List, Literal
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.radix.primitives.base import RadixPrimitiveComponentWithClassName
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 LiteralSliderOrientation = Literal["horizontal", "vertical"]
@@ -94,7 +95,6 @@ class SliderComponent(RadixPrimitiveComponentWithClassName):
         ...
 
 class SliderRoot(SliderComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     def add_style(self) -> dict[str, Any] | None: ...
     @overload
     @classmethod

+ 12 - 24
reflex/components/radix/themes/components/alert_dialog.py

@@ -1,9 +1,9 @@
 """Interactive components provided by @radix-ui/themes."""
-from typing import Any, Dict, Literal
+from typing import Literal
 
 from reflex.components.component import ComponentNamespace
 from reflex.components.el import elements
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 from ..base import RadixThemesComponent, RadixThemesTriggerComponent
@@ -19,16 +19,8 @@ class AlertDialogRoot(RadixThemesComponent):
     # The controlled open state of the dialog.
     open: Var[bool]
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the events triggers signatures for the component.
-
-        Returns:
-            The signatures of the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_OPEN_CHANGE: lambda e0: [e0],
-        }
+    # Fired when the open state changes.
+    on_open_change: EventHandler[lambda e0: [e0]]
 
 
 class AlertDialogTrigger(RadixThemesTriggerComponent):
@@ -48,18 +40,14 @@ class AlertDialogContent(elements.Div, RadixThemesComponent):
     # Whether to force mount the content on open.
     force_mount: Var[bool]
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the events triggers signatures for the component.
-
-        Returns:
-            The signatures of the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_OPEN_AUTO_FOCUS: lambda e0: [e0],
-            EventTriggers.ON_CLOSE_AUTO_FOCUS: lambda e0: [e0],
-            EventTriggers.ON_ESCAPE_KEY_DOWN: lambda e0: [e0],
-        }
+    # Fired when the dialog is opened.
+    on_open_auto_focus: EventHandler[lambda e0: [e0]]
+
+    # Fired when the dialog is closed.
+    on_close_auto_focus: EventHandler[lambda e0: [e0]]
+
+    # Fired when the escape key is pressed.
+    on_escape_key_down: EventHandler[lambda e0: [e0]]
 
 
 class AlertDialogTitle(RadixThemesComponent):

+ 2 - 4
reflex/components/radix/themes/components/alert_dialog.pyi

@@ -7,17 +7,16 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Dict, Literal
+from typing import Literal
 from reflex.components.component import ComponentNamespace
 from reflex.components.el import elements
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 from ..base import RadixThemesComponent, RadixThemesTriggerComponent
 
 LiteralContentSize = Literal["1", "2", "3", "4"]
 
 class AlertDialogRoot(RadixThemesComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore
@@ -172,7 +171,6 @@ class AlertDialogTrigger(RadixThemesTriggerComponent):
         ...
 
 class AlertDialogContent(elements.Div, RadixThemesComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 6 - 22
reflex/components/radix/themes/components/checkbox.py

@@ -1,11 +1,11 @@
 """Interactive components provided by @radix-ui/themes."""
 
-from typing import Any, Dict, Literal
+from typing import Literal
 
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.radix.themes.layout.flex import Flex
 from reflex.components.radix.themes.typography.text import Text
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 from ..base import (
@@ -59,16 +59,8 @@ class Checkbox(RadixThemesComponent):
     # Props to rename
     _rename_props = {"onChange": "onCheckedChange"}
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the events triggers signatures for the component.
-
-        Returns:
-            The signatures of the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CHANGE: lambda e0: [e0],
-        }
+    # Fired when the checkbox is checked or unchecked.
+    on_change: EventHandler[lambda e0: [e0]]
 
 
 class HighLevelCheckbox(RadixThemesComponent):
@@ -118,16 +110,8 @@ class HighLevelCheckbox(RadixThemesComponent):
     # Props to rename
     _rename_props = {"onChange": "onCheckedChange"}
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the events triggers signatures for the component.
-
-        Returns:
-            The signatures of the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CHANGE: lambda e0: [e0],
-        }
+    # Fired when the checkbox is checked or unchecked.
+    on_change: EventHandler[lambda e0: [e0]]
 
     @classmethod
     def create(

+ 2 - 4
reflex/components/radix/themes/components/checkbox.pyi

@@ -7,11 +7,11 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Dict, Literal
+from typing import Literal
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.radix.themes.layout.flex import Flex
 from reflex.components.radix.themes.typography.text import Text
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 from ..base import LiteralAccentColor, LiteralSpacing, RadixThemesComponent
 
@@ -19,7 +19,6 @@ LiteralCheckboxSize = Literal["1", "2", "3"]
 LiteralCheckboxVariant = Literal["classic", "surface", "soft"]
 
 class Checkbox(RadixThemesComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore
@@ -192,7 +191,6 @@ class Checkbox(RadixThemesComponent):
         ...
 
 class HighLevelCheckbox(RadixThemesComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 28 - 38
reflex/components/radix/themes/components/context_menu.py

@@ -1,8 +1,8 @@
 """Interactive components provided by @radix-ui/themes."""
-from typing import Any, Dict, List, Literal
+from typing import List, Literal
 
 from reflex.components.component import ComponentNamespace
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 from ..base import (
@@ -21,16 +21,8 @@ class ContextMenuRoot(RadixThemesComponent):
 
     _invalid_children: List[str] = ["ContextMenuItem"]
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the events triggers signatures for the component.
-
-        Returns:
-            The signatures of the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_OPEN_CHANGE: lambda e0: [e0],
-        }
+    # Fired when the open state changes.
+    on_open_change: EventHandler[lambda e0: [e0]]
 
 
 class ContextMenuTrigger(RadixThemesComponent):
@@ -69,20 +61,20 @@ class ContextMenuContent(RadixThemesComponent):
     # When true, overrides the side and aligns preferences to prevent collisions with boundary edges.
     avoid_collisions: Var[bool]
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the events triggers signatures for the component.
+    # Fired when the context menu is closed.
+    on_close_auto_focus: EventHandler[lambda e0: [e0]]
+
+    # Fired when the escape key is pressed.
+    on_escape_key_down: EventHandler[lambda e0: [e0]]
+
+    # Fired when a pointer down event happens outside the context menu.
+    on_pointer_down_outside: EventHandler[lambda e0: [e0]]
+
+    # Fired when focus moves outside the context menu.
+    on_focus_outside: EventHandler[lambda e0: [e0]]
 
-        Returns:
-            The signatures of the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CLOSE_AUTO_FOCUS: lambda e0: [e0],
-            EventTriggers.ON_ESCAPE_KEY_DOWN: lambda e0: [e0],
-            EventTriggers.ON_POINTER_DOWN_OUTSIDE: lambda e0: [e0],
-            EventTriggers.ON_FOCUS_OUTSIDE: lambda e0: [e0],
-            EventTriggers.ON_INTERACT_OUTSIDE: lambda e0: [e0],
-        }
+    # Fired when interacting outside the context menu.
+    on_interact_outside: EventHandler[lambda e0: [e0]]
 
 
 class ContextMenuSub(RadixThemesComponent):
@@ -112,19 +104,17 @@ class ContextMenuSubContent(RadixThemesComponent):
 
     _valid_parents: List[str] = ["ContextMenuSub"]
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the events triggers signatures for the component.
-
-        Returns:
-            The signatures of the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_ESCAPE_KEY_DOWN: lambda e0: [e0],
-            EventTriggers.ON_POINTER_DOWN_OUTSIDE: lambda e0: [e0],
-            EventTriggers.ON_FOCUS_OUTSIDE: lambda e0: [e0],
-            EventTriggers.ON_INTERACT_OUTSIDE: lambda e0: [e0],
-        }
+    # Fired when the escape key is pressed.
+    on_escape_key_down: EventHandler[lambda e0: [e0]]
+
+    # Fired when a pointer down event happens outside the context menu.
+    on_pointer_down_outside: EventHandler[lambda e0: [e0]]
+
+    # Fired when focus moves outside the context menu.
+    on_focus_outside: EventHandler[lambda e0: [e0]]
+
+    # Fired when interacting outside the context menu.
+    on_interact_outside: EventHandler[lambda e0: [e0]]
 
 
 class ContextMenuItem(RadixThemesComponent):

+ 2 - 5
reflex/components/radix/themes/components/context_menu.pyi

@@ -7,14 +7,13 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Dict, List, Literal
+from typing import List, Literal
 from reflex.components.component import ComponentNamespace
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 from ..base import LiteralAccentColor, RadixThemesComponent
 
 class ContextMenuRoot(RadixThemesComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore
@@ -180,7 +179,6 @@ class ContextMenuTrigger(RadixThemesComponent):
         ...
 
 class ContextMenuContent(RadixThemesComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore
@@ -510,7 +508,6 @@ class ContextMenuSubTrigger(RadixThemesComponent):
         ...
 
 class ContextMenuSubContent(RadixThemesComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 18 - 26
reflex/components/radix/themes/components/dialog.py

@@ -1,10 +1,10 @@
 """Interactive components provided by @radix-ui/themes."""
 
-from typing import Any, Dict, Literal
+from typing import Literal
 
 from reflex.components.component import ComponentNamespace
 from reflex.components.el import elements
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 from ..base import (
@@ -21,16 +21,8 @@ class DialogRoot(RadixThemesComponent):
     # The controlled open state of the dialog.
     open: Var[bool]
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the events triggers signatures for the component.
-
-        Returns:
-            The signatures of the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_OPEN_CHANGE: lambda e0: [e0],
-        }
+    # Fired when the open state changes.
+    on_open_change: EventHandler[lambda e0: [e0]]
 
 
 class DialogTrigger(RadixThemesTriggerComponent):
@@ -53,20 +45,20 @@ class DialogContent(elements.Div, RadixThemesComponent):
     # DialogContent size "1" - "4"
     size: Var[Literal["1", "2", "3", "4"]]
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the events triggers signatures for the component.
-
-        Returns:
-            The signatures of the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_OPEN_AUTO_FOCUS: lambda e0: [e0],
-            EventTriggers.ON_CLOSE_AUTO_FOCUS: lambda e0: [e0],
-            EventTriggers.ON_ESCAPE_KEY_DOWN: lambda e0: [e0],
-            EventTriggers.ON_POINTER_DOWN_OUTSIDE: lambda e0: [e0],
-            EventTriggers.ON_INTERACT_OUTSIDE: lambda e0: [e0],
-        }
+    # Fired when the dialog is opened.
+    on_open_auto_focus: EventHandler[lambda e0: [e0]]
+
+    # Fired when the dialog is closed.
+    on_close_auto_focus: EventHandler[lambda e0: [e0]]
+
+    # Fired when the escape key is pressed.
+    on_escape_key_down: EventHandler[lambda e0: [e0]]
+
+    # Fired when the pointer is down outside the dialog.
+    on_pointer_down_outside: EventHandler[lambda e0: [e0]]
+
+    # Fired when the pointer interacts outside the dialog.
+    on_interact_outside: EventHandler[lambda e0: [e0]]
 
 
 class DialogDescription(RadixThemesComponent):

+ 2 - 4
reflex/components/radix/themes/components/dialog.pyi

@@ -7,15 +7,14 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Dict, Literal
+from typing import Literal
 from reflex.components.component import ComponentNamespace
 from reflex.components.el import elements
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 from ..base import RadixThemesComponent, RadixThemesTriggerComponent
 
 class DialogRoot(RadixThemesComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore
@@ -249,7 +248,6 @@ class DialogTitle(RadixThemesComponent):
         ...
 
 class DialogContent(elements.Div, RadixThemesComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 31 - 57
reflex/components/radix/themes/components/dropdown_menu.py

@@ -1,8 +1,8 @@
 """Interactive components provided by @radix-ui/themes."""
-from typing import Any, Dict, List, Literal, Union
+from typing import Dict, List, Literal, Union
 
 from reflex.components.component import ComponentNamespace
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 from ..base import (
@@ -47,16 +47,8 @@ class DropdownMenuRoot(RadixThemesComponent):
 
     _invalid_children: List[str] = ["DropdownMenuItem"]
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the events triggers signatures for the component.
-
-        Returns:
-            The signatures of the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_OPEN_CHANGE: lambda e0: [e0],
-        }
+    # Fired when the open state changes.
+    on_open_change: EventHandler[lambda e0: [e0]]
 
 
 class DropdownMenuTrigger(RadixThemesTriggerComponent):
@@ -125,20 +117,20 @@ class DropdownMenuContent(RadixThemesComponent):
     # Whether to hide the content when the trigger becomes fully occluded. Defaults to False.
     hide_when_detached: Var[bool]
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the events triggers signatures for the component.
+    # Fired when the dialog is closed.
+    on_close_auto_focus: EventHandler[lambda e0: [e0]]
+
+    # Fired when the escape key is pressed.
+    on_escape_key_down: EventHandler[lambda e0: [e0]]
+
+    # Fired when the pointer is down outside the dialog.
+    on_pointer_down_outside: EventHandler[lambda e0: [e0]]
+
+    # Fired when focus moves outside the dialog.
+    on_focus_outside: EventHandler[lambda e0: [e0]]
 
-        Returns:
-            The signatures of the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CLOSE_AUTO_FOCUS: lambda e0: [e0],
-            EventTriggers.ON_ESCAPE_KEY_DOWN: lambda e0: [e0],
-            EventTriggers.ON_POINTER_DOWN_OUTSIDE: lambda e0: [e0],
-            EventTriggers.ON_FOCUS_OUTSIDE: lambda e0: [e0],
-            EventTriggers.ON_INTERACT_OUTSIDE: lambda e0: [e0],
-        }
+    # Fired when the pointer interacts outside the dialog.
+    on_interact_outside: EventHandler[lambda e0: [e0]]
 
 
 class DropdownMenuSubTrigger(RadixThemesTriggerComponent):
@@ -169,16 +161,8 @@ class DropdownMenuSub(RadixThemesComponent):
     # The open state of the submenu when it is initially rendered. Use when you do not need to control its open state.
     default_open: Var[bool]
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the events triggers signatures for the component.
-
-        Returns:
-            The signatures of the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_OPEN_CHANGE: lambda e0: [e0.target.value],
-        }
+    # Fired when the open state changes.
+    on_open_change: EventHandler[lambda e0: [e0.target.value]]
 
 
 class DropdownMenuSubContent(RadixThemesComponent):
@@ -218,19 +202,17 @@ class DropdownMenuSubContent(RadixThemesComponent):
 
     _valid_parents: List[str] = ["DropdownMenuSub"]
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the events triggers signatures for the component.
+    # Fired when the escape key is pressed.
+    on_escape_key_down: EventHandler[lambda e0: [e0]]
+
+    # Fired when the pointer is down outside the dialog.
+    on_pointer_down_outside: EventHandler[lambda e0: [e0]]
 
-        Returns:
-            The signatures of the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_ESCAPE_KEY_DOWN: lambda e0: [e0],
-            EventTriggers.ON_POINTER_DOWN_OUTSIDE: lambda e0: [e0],
-            EventTriggers.ON_FOCUS_OUTSIDE: lambda e0: [e0],
-            EventTriggers.ON_INTERACT_OUTSIDE: lambda e0: [e0],
-        }
+    # Fired when focus moves outside the dialog.
+    on_focus_outside: EventHandler[lambda e0: [e0]]
+
+    # Fired when the pointer interacts outside the dialog.
+    on_interact_outside: EventHandler[lambda e0: [e0]]
 
 
 class DropdownMenuItem(RadixThemesComponent):
@@ -255,16 +237,8 @@ class DropdownMenuItem(RadixThemesComponent):
 
     _valid_parents: List[str] = ["DropdownMenuContent", "DropdownMenuSubContent"]
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the events triggers signatures for the component.
-
-        Returns:
-            The signatures of the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_SELECT: lambda e0: [e0.target.value],
-        }
+    # Fired when the item is selected.
+    on_select: EventHandler[lambda e0: [e0.target.value]]
 
 
 class DropdownMenuSeparator(RadixThemesComponent):

+ 2 - 7
reflex/components/radix/themes/components/dropdown_menu.pyi

@@ -7,9 +7,9 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Dict, List, Literal, Union
+from typing import Dict, List, Literal, Union
 from reflex.components.component import ComponentNamespace
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 from ..base import LiteralAccentColor, RadixThemesComponent, RadixThemesTriggerComponent
 
@@ -21,7 +21,6 @@ LiteralAlignType = Literal["start", "center", "end"]
 LiteralStickyType = Literal["partial", "always"]
 
 class DropdownMenuRoot(RadixThemesComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore
@@ -183,7 +182,6 @@ class DropdownMenuTrigger(RadixThemesTriggerComponent):
         ...
 
 class DropdownMenuContent(RadixThemesComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore
@@ -465,7 +463,6 @@ class DropdownMenuSubTrigger(RadixThemesTriggerComponent):
         ...
 
 class DropdownMenuSub(RadixThemesComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore
@@ -552,7 +549,6 @@ class DropdownMenuSub(RadixThemesComponent):
         ...
 
 class DropdownMenuSubContent(RadixThemesComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore
@@ -673,7 +669,6 @@ class DropdownMenuSubContent(RadixThemesComponent):
         ...
 
 class DropdownMenuItem(RadixThemesComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 4 - 12
reflex/components/radix/themes/components/hover_card.py

@@ -1,9 +1,9 @@
 """Interactive components provided by @radix-ui/themes."""
-from typing import Any, Dict, Literal
+from typing import Literal
 
 from reflex.components.component import ComponentNamespace
 from reflex.components.el import elements
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 from ..base import (
@@ -29,16 +29,8 @@ class HoverCardRoot(RadixThemesComponent):
     # The duration from when the mouse leaves the trigger until the hover card closes.
     close_delay: Var[int]
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the events triggers signatures for the component.
-
-        Returns:
-            The signatures of the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_OPEN_CHANGE: lambda e0: [e0],
-        }
+    # Fired when the open state changes.
+    on_open_change: EventHandler[lambda e0: [e0]]
 
 
 class HoverCardTrigger(RadixThemesTriggerComponent):

+ 2 - 3
reflex/components/radix/themes/components/hover_card.pyi

@@ -7,15 +7,14 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Dict, Literal
+from typing import Literal
 from reflex.components.component import ComponentNamespace
 from reflex.components.el import elements
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 from ..base import RadixThemesComponent, RadixThemesTriggerComponent
 
 class HoverCardRoot(RadixThemesComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 21 - 27
reflex/components/radix/themes/components/popover.py

@@ -1,9 +1,9 @@
 """Interactive components provided by @radix-ui/themes."""
-from typing import Any, Dict, Literal
+from typing import Literal
 
 from reflex.components.component import ComponentNamespace
 from reflex.components.el import elements
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 from ..base import (
@@ -23,16 +23,8 @@ class PopoverRoot(RadixThemesComponent):
     # The modality of the popover. When set to true, interaction with outside elements will be disabled and only popover content will be visible to screen readers.
     modal: Var[bool]
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the events triggers signatures for the component.
-
-        Returns:
-            The signatures of the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_OPEN_CHANGE: lambda e0: [e0],
-        }
+    # Fired when the open state changes.
+    on_open_change: EventHandler[lambda e0: [e0]]
 
 
 class PopoverTrigger(RadixThemesTriggerComponent):
@@ -64,21 +56,23 @@ class PopoverContent(elements.Div, RadixThemesComponent):
     # When true, overrides the side andalign preferences to prevent collisions with boundary edges.
     avoid_collisions: Var[bool]
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the events triggers signatures for the component.
-
-        Returns:
-            The signatures of the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_OPEN_AUTO_FOCUS: lambda e0: [e0],
-            EventTriggers.ON_CLOSE_AUTO_FOCUS: lambda e0: [e0],
-            EventTriggers.ON_ESCAPE_KEY_DOWN: lambda e0: [e0],
-            EventTriggers.ON_POINTER_DOWN_OUTSIDE: lambda e0: [e0],
-            EventTriggers.ON_FOCUS_OUTSIDE: lambda e0: [e0],
-            EventTriggers.ON_INTERACT_OUTSIDE: lambda e0: [e0],
-        }
+    # Fired when the dialog is opened.
+    on_open_auto_focus: EventHandler[lambda e0: [e0]]
+
+    # Fired when the dialog is closed.
+    on_close_auto_focus: EventHandler[lambda e0: [e0]]
+
+    # Fired when the escape key is pressed.
+    on_escape_key_down: EventHandler[lambda e0: [e0]]
+
+    # Fired when the pointer is down outside the dialog.
+    on_pointer_down_outside: EventHandler[lambda e0: [e0]]
+
+    # Fired when focus moves outside the dialog.
+    on_focus_outside: EventHandler[lambda e0: [e0]]
+
+    # Fired when the pointer interacts outside the dialog.
+    on_interact_outside: EventHandler[lambda e0: [e0]]
 
 
 class PopoverClose(RadixThemesTriggerComponent):

+ 2 - 4
reflex/components/radix/themes/components/popover.pyi

@@ -7,15 +7,14 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Dict, Literal
+from typing import Literal
 from reflex.components.component import ComponentNamespace
 from reflex.components.el import elements
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 from ..base import RadixThemesComponent, RadixThemesTriggerComponent
 
 class PopoverRoot(RadixThemesComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore
@@ -172,7 +171,6 @@ class PopoverTrigger(RadixThemesTriggerComponent):
         ...
 
 class PopoverContent(elements.Div, RadixThemesComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 4 - 12
reflex/components/radix/themes/components/radio_group.py

@@ -1,13 +1,13 @@
 """Interactive components provided by @radix-ui/themes."""
 from __future__ import annotations
 
-from typing import Any, Dict, List, Literal, Optional, Union
+from typing import List, Literal, Optional, Union
 
 import reflex as rx
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.radix.themes.layout.flex import Flex
 from reflex.components.radix.themes.typography.text import Text
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 from ..base import (
@@ -54,16 +54,8 @@ class RadioGroupRoot(RadixThemesComponent):
     # Props to rename
     _rename_props = {"onChange": "onValueChange"}
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the events triggers signatures for the component.
-
-        Returns:
-            The signatures of the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CHANGE: lambda e0: [e0],
-        }
+    # Fired when the value of the radio group changes.
+    on_change: EventHandler[lambda e0: [e0]]
 
 
 class RadioGroupItem(RadixThemesComponent):

+ 2 - 3
reflex/components/radix/themes/components/radio_group.pyi

@@ -7,19 +7,18 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Dict, List, Literal, Optional, Union
+from typing import List, Literal, Optional, Union
 import reflex as rx
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.radix.themes.layout.flex import Flex
 from reflex.components.radix.themes.typography.text import Text
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 from ..base import LiteralAccentColor, LiteralSpacing, RadixThemesComponent
 
 LiteralFlexDirection = Literal["row", "column", "row-reverse", "column-reverse"]
 
 class RadioGroupRoot(RadixThemesComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 12 - 23
reflex/components/radix/themes/components/select.py

@@ -1,9 +1,8 @@
 """Interactive components provided by @radix-ui/themes."""
-from typing import Any, Dict, List, Literal, Union
+from typing import List, Literal, Union
 
 import reflex as rx
 from reflex.components.component import Component, ComponentNamespace
-from reflex.constants import EventTriggers
 from reflex.vars import Var
 
 from ..base import (
@@ -45,17 +44,11 @@ class SelectRoot(RadixThemesComponent):
     # Props to rename
     _rename_props = {"onChange": "onValueChange"}
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the events triggers signatures for the component.
+    # Fired when the value of the select changes.
+    on_change: rx.EventHandler[lambda e0: [e0]]
 
-        Returns:
-            The signatures of the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_OPEN_CHANGE: lambda e0: [e0],
-            EventTriggers.ON_CHANGE: lambda e0: [e0],
-        }
+    # Fired when the select is opened or closed.
+    on_open_change: rx.EventHandler[lambda e0: [e0]]
 
 
 class SelectTrigger(RadixThemesComponent):
@@ -107,18 +100,14 @@ class SelectContent(RadixThemesComponent):
     # The vertical distance in pixels from the anchor. Only available when position is set to popper.
     align_offset: Var[int]
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the events triggers signatures for the component.
+    # Fired when the select content is closed.
+    on_close_auto_focus: rx.EventHandler[lambda e0: [e0]]
 
-        Returns:
-            The signatures of the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CLOSE_AUTO_FOCUS: lambda e0: [e0],
-            EventTriggers.ON_ESCAPE_KEY_DOWN: lambda e0: [e0],
-            EventTriggers.ON_POINTER_DOWN_OUTSIDE: lambda e0: [e0],
-        }
+    # Fired when the escape key is pressed.
+    on_escape_key_down: rx.EventHandler[lambda e0: [e0]]
+
+    # Fired when a pointer down event happens outside the select content.
+    on_pointer_down_outside: rx.EventHandler[lambda e0: [e0]]
 
 
 class SelectGroup(RadixThemesComponent):

+ 1 - 4
reflex/components/radix/themes/components/select.pyi

@@ -7,15 +7,13 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Dict, List, Literal, Union
+from typing import List, Literal, Union
 import reflex as rx
 from reflex.components.component import Component, ComponentNamespace
-from reflex.constants import EventTriggers
 from reflex.vars import Var
 from ..base import LiteralAccentColor, LiteralRadius, RadixThemesComponent
 
 class SelectRoot(RadixThemesComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore
@@ -277,7 +275,6 @@ class SelectTrigger(RadixThemesComponent):
         ...
 
 class SelectContent(RadixThemesComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 6 - 12
reflex/components/radix/themes/components/slider.py

@@ -1,8 +1,8 @@
 """Interactive components provided by @radix-ui/themes."""
-from typing import Any, Dict, List, Literal, Optional, Union
+from typing import List, Literal, Optional, Union
 
 from reflex.components.component import Component
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 from ..base import (
@@ -61,17 +61,11 @@ class Slider(RadixThemesComponent):
     # Props to rename
     _rename_props = {"onChange": "onValueChange"}
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the events triggers signatures for the component.
+    # Fired when the value of the slider changes.
+    on_change: EventHandler[lambda e0: [e0]]
 
-        Returns:
-            The signatures of the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CHANGE: lambda e0: [e0],
-            EventTriggers.ON_VALUE_COMMIT: lambda e0: [e0],
-        }
+    # Fired when a thumb is released after being dragged.
+    on_value_commit: EventHandler[lambda e0: [e0]]
 
     @classmethod
     def create(

+ 2 - 3
reflex/components/radix/themes/components/slider.pyi

@@ -7,14 +7,13 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Dict, List, Literal, Optional, Union
+from typing import List, Literal, Optional, Union
 from reflex.components.component import Component
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 from ..base import LiteralAccentColor, RadixThemesComponent
 
 class Slider(RadixThemesComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 4 - 12
reflex/components/radix/themes/components/switch.py

@@ -1,7 +1,7 @@
 """Interactive components provided by @radix-ui/themes."""
-from typing import Any, Dict, Literal
+from typing import Literal
 
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 from ..base import (
@@ -56,16 +56,8 @@ class Switch(RadixThemesComponent):
     # Props to rename
     _rename_props = {"onChange": "onCheckedChange"}
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the event triggers that pass the component's value to the handler.
-
-        Returns:
-            A dict mapping the event trigger name to the argspec passed to the handler.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CHANGE: lambda checked: [checked],
-        }
+    # Fired when the value of the switch changes
+    on_change: EventHandler[lambda checked: [checked]]
 
 
 switch = Switch.create

+ 2 - 3
reflex/components/radix/themes/components/switch.pyi

@@ -7,15 +7,14 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Dict, Literal
-from reflex.constants import EventTriggers
+from typing import Literal
+from reflex.event import EventHandler
 from reflex.vars import Var
 from ..base import LiteralAccentColor, RadixThemesComponent
 
 LiteralSwitchSize = Literal["1", "2", "3"]
 
 class Switch(RadixThemesComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 3 - 11
reflex/components/radix/themes/components/tabs.py

@@ -5,7 +5,7 @@ from typing import Any, Dict, List, Literal
 
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.core.colors import color
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 from ..base import (
@@ -33,16 +33,8 @@ class TabsRoot(RadixThemesComponent):
     # Props to rename
     _rename_props = {"onChange": "onValueChange"}
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the events triggers signatures for the component.
-
-        Returns:
-            The signatures of the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CHANGE: lambda e0: [e0],
-        }
+    # Fired when the value of the tabs changes.
+    on_change: EventHandler[lambda e0: [e0]]
 
     def add_style(self) -> Dict[str, Any] | None:
         """Add style for the component.

+ 1 - 2
reflex/components/radix/themes/components/tabs.pyi

@@ -10,14 +10,13 @@ from reflex.style import Style
 from typing import Any, Dict, List, Literal
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.core.colors import color
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 from ..base import LiteralAccentColor, RadixThemesComponent
 
 vertical_orientation_css = "&[data-orientation='vertical']"
 
 class TabsRoot(RadixThemesComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     def add_style(self) -> Dict[str, Any] | None: ...
     @overload
     @classmethod

+ 17 - 17
reflex/components/radix/themes/components/text_area.py

@@ -1,10 +1,10 @@
 """Interactive components provided by @radix-ui/themes."""
-from typing import Any, Dict, Literal, Union
+from typing import Literal, Union
 
 from reflex.components.component import Component
 from reflex.components.core.debounce import DebounceInput
 from reflex.components.el import elements
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 
 from ..base import (
@@ -80,6 +80,21 @@ class TextArea(RadixThemesComponent, elements.Textarea):
     # How the text in the textarea is to be wrapped when submitting the form
     wrap: Var[str]
 
+    # Fired when the value of the textarea changes.
+    on_change: EventHandler[lambda e0: [e0.target.value]]
+
+    # Fired when the textarea is focused.
+    on_focus: EventHandler[lambda e0: [e0.target.value]]
+
+    # Fired when the textarea is blurred.
+    on_blur: EventHandler[lambda e0: [e0.target.value]]
+
+    # Fired when a key is pressed down.
+    on_key_down: EventHandler[lambda e0: [e0.key]]
+
+    # Fired when a key is released.
+    on_key_up: EventHandler[lambda e0: [e0.key]]
+
     @classmethod
     def create(cls, *children, **props) -> Component:
         """Create an Input component.
@@ -96,20 +111,5 @@ class TextArea(RadixThemesComponent, elements.Textarea):
             return DebounceInput.create(super().create(*children, **props))
         return super().create(*children, **props)
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the event triggers that pass the component's value to the handler.
-
-        Returns:
-            A dict mapping the event trigger to the var that is passed to the handler.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CHANGE: lambda e0: [e0.target.value],
-            EventTriggers.ON_FOCUS: lambda e0: [e0.target.value],
-            EventTriggers.ON_BLUR: lambda e0: [e0.target.value],
-            EventTriggers.ON_KEY_DOWN: lambda e0: [e0.key],
-            EventTriggers.ON_KEY_UP: lambda e0: [e0.key],
-        }
-
 
 text_area = TextArea.create

+ 2 - 3
reflex/components/radix/themes/components/text_area.pyi

@@ -7,11 +7,11 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Dict, Literal, Union
+from typing import Literal, Union
 from reflex.components.component import Component
 from reflex.components.core.debounce import DebounceInput
 from reflex.components.el import elements
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.vars import Var
 from ..base import LiteralAccentColor, LiteralRadius, RadixThemesComponent
 
@@ -280,6 +280,5 @@ class TextArea(RadixThemesComponent, elements.Textarea):
             The component.
         """
         ...
-    def get_event_triggers(self) -> Dict[str, Any]: ...
 
 text_area = TextArea.create

+ 17 - 17
reflex/components/radix/themes/components/text_field.py

@@ -1,13 +1,13 @@
 """Interactive components provided by @radix-ui/themes."""
 from __future__ import annotations
 
-from typing import Any, Dict, Literal, Union
+from typing import Literal, Union
 
 from reflex.components.base.fragment import Fragment
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.core.debounce import DebounceInput
 from reflex.components.el import elements
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.style import Style, format_as_emotion
 from reflex.utils import console
 from reflex.vars import Var
@@ -72,6 +72,21 @@ class TextFieldRoot(elements.Div, RadixThemesComponent):
     # Value of the input
     value: Var[Union[str, int, float]]
 
+    # Fired when the value of the textarea changes.
+    on_change: EventHandler[lambda e0: [e0.target.value]]
+
+    # Fired when the textarea is focused.
+    on_focus: EventHandler[lambda e0: [e0.target.value]]
+
+    # Fired when the textarea is blurred.
+    on_blur: EventHandler[lambda e0: [e0.target.value]]
+
+    # Fired when a key is pressed down.
+    on_key_down: EventHandler[lambda e0: [e0.key]]
+
+    # Fired when a key is released.
+    on_key_up: EventHandler[lambda e0: [e0.key]]
+
     @classmethod
     def create(cls, *children, **props) -> Component:
         """Create an Input component.
@@ -163,21 +178,6 @@ class TextFieldRoot(elements.Div, RadixThemesComponent):
         )
         return cls.create(*children, **props)
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the event triggers that pass the component's value to the handler.
-
-        Returns:
-            A dict mapping the event trigger to the var that is passed to the handler.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CHANGE: lambda e0: [e0.target.value],
-            EventTriggers.ON_FOCUS: lambda e0: [e0.target.value],
-            EventTriggers.ON_BLUR: lambda e0: [e0.target.value],
-            EventTriggers.ON_KEY_DOWN: lambda e0: [e0.key],
-            EventTriggers.ON_KEY_UP: lambda e0: [e0.key],
-        }
-
 
 class TextFieldSlot(RadixThemesComponent):
     """Contains icons or buttons associated with an Input."""

+ 2 - 3
reflex/components/radix/themes/components/text_field.pyi

@@ -7,12 +7,12 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Dict, Literal, Union
+from typing import Literal, Union
 from reflex.components.base.fragment import Fragment
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.core.debounce import DebounceInput
 from reflex.components.el import elements
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.style import Style, format_as_emotion
 from reflex.utils import console
 from reflex.vars import Var
@@ -270,7 +270,6 @@ class TextFieldRoot(elements.Div, RadixThemesComponent):
     def create_root_deprecated(cls, *children, **props) -> Component: ...
     @classmethod
     def create_input_deprecated(cls, *children, **props) -> Component: ...
-    def get_event_triggers(self) -> Dict[str, Any]: ...
 
 class TextFieldSlot(RadixThemesComponent):
     @overload

+ 9 - 13
reflex/components/radix/themes/components/tooltip.py

@@ -1,8 +1,8 @@
 """Interactive components provided by @radix-ui/themes."""
-from typing import Any, Dict, Literal, Union
+from typing import Dict, Literal, Union
 
 from reflex.components.component import Component
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.utils import format
 from reflex.vars import Var
 
@@ -83,18 +83,14 @@ class Tooltip(RadixThemesComponent):
     # By default, screenreaders will announce the content inside the component. If this is not descriptive enough, or you have content that cannot be announced, use aria-label as a more descriptive label.
     aria_label: Var[str]
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the events triggers signatures for the component.
+    # Fired when the open state changes.
+    on_open_change: EventHandler[lambda e0: [e0.target.value]]
 
-        Returns:
-            The signatures of the event triggers.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_OPEN_CHANGE: lambda e0: [e0.target.value],
-            EventTriggers.ON_ESCAPE_KEY_DOWN: lambda e0: [e0.target.value],
-            EventTriggers.ON_POINTER_DOWN_OUTSIDE: lambda e0: [e0.target.value],
-        }
+    # Fired when the escape key is pressed.
+    on_escape_key_down: EventHandler[lambda e0: [e0.target.value]]
+
+    # Fired when the pointer is down outside the tooltip.
+    on_pointer_down_outside: EventHandler[lambda e0: [e0.target.value]]
 
     @classmethod
     def create(cls, *children, **props) -> Component:

+ 2 - 3
reflex/components/radix/themes/components/tooltip.pyi

@@ -7,9 +7,9 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Any, Dict, Literal, Union
+from typing import Dict, Literal, Union
 from reflex.components.component import Component
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.utils import format
 from reflex.vars import Var
 from ..base import RadixThemesComponent
@@ -19,7 +19,6 @@ LiteralAlignType = Literal["start", "center", "end"]
 LiteralStickyType = Literal["partial", "always"]
 
 class Tooltip(RadixThemesComponent):
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore

+ 34 - 25
reflex/components/suneditor/editor.py

@@ -2,11 +2,11 @@
 from __future__ import annotations
 
 import enum
-from typing import Any, Dict, List, Literal, Optional, Union
+from typing import Dict, List, Literal, Optional, Union
 
 from reflex.base import Base
 from reflex.components.component import Component, NoSSRComponent
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.utils.format import to_camel_case
 from reflex.utils.imports import ImportDict, ImportVar
 from reflex.vars import Var
@@ -176,6 +176,38 @@ class Editor(NoSSRComponent):
     # default: False
     disable_toolbar: Var[bool]
 
+    # Fired when the editor content changes.
+    on_change: EventHandler[lambda content: [content]]
+
+    # Fired when the something is inputted in the editor.
+    on_input: EventHandler[lambda e: [e]]
+
+    # Fired when the editor loses focus.
+    on_blur: EventHandler[lambda e, content: [content]]
+
+    # Fired when the editor is loaded.
+    on_load: EventHandler[lambda reload: [reload]]
+
+    # Fired when the editor is resized.
+    on_resize_editor: EventHandler[lambda height, prev_height: [height, prev_height]]
+
+    # Fired when the editor content is copied.
+    on_copy: EventHandler[lambda e, clipboard_data: [clipboard_data]]
+
+    # Fired when the editor content is cut.
+    on_cut: EventHandler[lambda e, clipboard_data: [clipboard_data]]
+
+    # Fired when the editor content is pasted.
+    on_paste: EventHandler[
+        lambda e, clean_data, max_char_count: [clean_data, max_char_count]
+    ]
+
+    # Fired when the code view is toggled.
+    toggle_code_view: EventHandler[lambda is_code_view: [is_code_view]]
+
+    # Fired when the full screen mode is toggled.
+    toggle_full_screen: EventHandler[lambda is_full_screen: [is_full_screen]]
+
     def add_imports(self) -> ImportDict:
         """Add imports for the Editor component.
 
@@ -186,29 +218,6 @@ class Editor(NoSSRComponent):
             "": ImportVar(tag="suneditor/dist/css/suneditor.min.css", install=False)
         }
 
-    def get_event_triggers(self) -> Dict[str, Any]:
-        """Get the event triggers that pass the component's value to the handler.
-
-        Returns:
-            A dict mapping the event trigger to the var that is passed to the handler.
-        """
-        return {
-            **super().get_event_triggers(),
-            EventTriggers.ON_CHANGE: lambda content: [content],
-            "on_input": lambda _e: [_e],
-            EventTriggers.ON_BLUR: lambda _e, content: [content],
-            "on_load": lambda reload: [reload],
-            "on_resize_editor": lambda height, prev_height: [height, prev_height],
-            "on_copy": lambda _e, clipboard_data: [clipboard_data],
-            "on_cut": lambda _e, clipboard_data: [clipboard_data],
-            "on_paste": lambda _e, clean_data, max_char_count: [
-                clean_data,
-                max_char_count,
-            ],
-            "toggle_code_view": lambda is_code_view: [is_code_view],
-            "toggle_full_screen": lambda is_full_screen: [is_full_screen],
-        }
-
     @classmethod
     def create(cls, set_options: Optional[EditorOptions] = None, **props) -> Component:
         """Create an instance of Editor. No children allowed.

+ 2 - 3
reflex/components/suneditor/editor.pyi

@@ -8,10 +8,10 @@ from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
 import enum
-from typing import Any, Dict, List, Literal, Optional, Union
+from typing import Dict, List, Literal, Optional, Union
 from reflex.base import Base
 from reflex.components.component import Component, NoSSRComponent
-from reflex.constants import EventTriggers
+from reflex.event import EventHandler
 from reflex.utils.format import to_camel_case
 from reflex.utils.imports import ImportDict, ImportVar
 from reflex.vars import Var
@@ -49,7 +49,6 @@ class EditorOptions(Base):
 
 class Editor(NoSSRComponent):
     def add_imports(self) -> ImportDict: ...
-    def get_event_triggers(self) -> Dict[str, Any]: ...
     @overload
     @classmethod
     def create(  # type: ignore