reflex icon indicating copy to clipboard operation
reflex copied to clipboard

[Enhancement] Improve Event Triggers with Event Detail Objects

Open Cheesy-Brik opened this issue 3 years ago β€’ 2 comments

Main Idea

Allow for more functionality in the event hook functions without bloating the Base Event Triggers and without Overwhelming the developer with too many options.

Implementation

Using unique "event detail objects" for each event hook, we can gain extra detail and allow you to only pull out the information you need. Each event detail object will be unique to each event hook and each have their own props to use. To keep simplicity and to not break old code, functions passed to event hooks should be processed in 2 ways.

  1. If the passed function has no Args, run the function.
  2. If the passed function has 1 Arg pass in an event detail object containing extra information about the event Say for example you wanted to have something happen whenever the user clicks. Simply make a function that takes no Args and you're fine! However, if you want extra info about the interaction, you can simply give the function 1 argument, then the event handler would pass in an object that contains that extra info.

To reduce clutter and make sure the objects that are passed to the event functions are unique, all event detail objects will be inherit from a base class and be in a separate module event (pc.event).

Type hinting is not necessary.

Syntax Example

Here is a basic example.

...
class State(pc.State):
    
    pos = (0,0)

    def moved(self, event_object):
        pos = event_object.mouse_position
...
pc.text(str(State.pos), on_mouse_move = State.moved)
...

This piece of code displays the current mouse's position at all times, best part is, it's simple, but allows you to say add

Pros

  • Because each event detail object is seperate, the user's IDE can use autocomplete to know what information is available to them.
  • Allows for more functionality to be added to event hooks without adding a ton of new ones.

Cons

  • Breaks some old code
  • Requires extra memorization from the developer.

Proposed Event Detail Props (names subject to change)

There are some extra event hooks here as well (I think they work well with this feature)

  • All Event Details have these props, any missing event triggers just use these.
    • when:DateTime
    • keys_down:list[str] (Pressed before the event occured)
    • mouse_buttons_down:list[str] (Pressed before the event occured)
  • on_focus, on_blur
    • child_index:int (the child that was focused/blurred, is None if the object itself was focused/blurred)
  • on_mouse_out, on_mouse_leave, on_mouse_move, on_mouse_over, on_mouse_enter
    • mouse_position:tuple[int, int]
    • mouse_in_window:bool
  • on_scroll
    • direction:str
  • on_mouse_down, on_click, on_mouse_up, on_double_click
    • mouse_button
  • New
  • on_key_down
    • key:str
  • on_key_up
    • key:str

Extra

The new key event handling would most likely require some kind of keycode literal for ease of use. This design doc is already long, but I feel most of these are self explanatory and ofc new details could always be added on later.

I will now show how this idea helps some previous complaints, or this idea could be easily extended to help those complaints. Helps with:

  • #55 (This method of object oriented event details is very conducive to custom hooks)
  • #169
  • #298
  • #448
  • #463

Cheesy-Brik avatar Feb 11 '23 10:02 Cheesy-Brik

Alternatively, you can throw all parameters passed to the js event.

For example, when you change row selection in antd callback, you receive three arguments (selectedRowKeys, selectedRows, selection type) and throw them all to the server, which can be treated as connected logic.

Since python implementations cannot be treated as first-class objects in js, we believe this implementation is essential for using the universal js library.

w200kr avatar Feb 12 '23 14:02 w200kr

I like this - adding it to the next milestone

picklelo avatar Feb 12 '23 18:02 picklelo

What is the status of this? Can I use the example to get the user's mouse position in an rx.image?

oriaj3 avatar Feb 29 '24 16:02 oriaj3