Open mwx23 opened 1 year ago
Hi @mwx23,
Lately I've been using tailwindcss and daisyui for my UI css
Nice! I didn't know daisyui, but it looks pretty cool and versatile. If we can resolve your issues we could make package for lona like https://github.com/lona-web-org/lona-bootstrap-5
I've tried
handle_input_event_root
on aLonaView
andhandle_input_event
on aWidget
but that doesn't seem to work unless aTextInput
is involved and focused.If I were to generalise the issue even more, is there a way to subscribe to frontend DOM events from the backend?
Actually, that is exactly how events are implemented. Every node has a list of events it can fire (Node.events
). This list is empty by default, but some nodes from the standard library like lona.html.Button
come pre-configured with for click events. You can add any event type from lona.html
to any node (currently implemented: CLICK, FOCUS, CHANGE, BLUR
).
from lona.html import CLICK, FOCUS, CHANGE, BLUR
from lona.html import Div
my_div = Div(events=[CLICK])
The information that my_div
can be clicked gets send to JavaScript client with the actual HTML. When the client renders
my_div
a JavaScript event handler gets setup that produces a high-level event that can be send back over the websocket, so
Lona can call my_div.handle_click()
.
That means: With this approach, you can only handle events that are supported by both the server and the client, and are configured correctly.
My general question is it possible to capture a keypress event and have it sent to the backend? [...] I can write a frontend widget to do this (I think) but is there a more
lona
way to achieve this?
Currently, that is the way to go. Lona frontend widgets can send custom events. That means you can create a Modal widget, with a specialized frontend widget that captures global keypresses and sends event to the server to close the modal. That's what i currently do in bootstrap code aswell.
There are ideas to extend the event API to make code like this work:
from lona.html import KEY_ALT, KEY_T
from lona.html import Div
my_div = Div(events=[KEY_ALT + KEY_T) # simple key binding
but the problem with first implementation was that most elements have to set tabindex
to be able to emit key events, and then the key events only work when the right container is focused. The next idea was to let the view describe the key bindings globally like this:
from lona.html import KEY_ALT, KEY_T
from lona import LonaView
class MyLonaView(LonaView):
KEY_BINDINGS = {
KEY_ALT + KEY_T: self.handle_alt_t,
}
but until now the need was not big enough to implement something like this. Also i don't have a good idea yet how to connect global key event (like in implementation 2) to a very specific node like a daisyui modal.
Hi @mwx23,
I did some prototyping came up with this API:
from lona.html import HTML, Div, H1, KeyboardShortcuts
from lona import LonaView
from my_code import Modal
class MyLonaView(LonaView):
def handle_alt_enter(self, input_event):
print('ALT + Enter was pressed')
def handle_arrow_up(self, input_event):
print('Arrow Up was pressed')
def dismiss_modal(self, input_event):
with self.html.lock:
if self.modal.visible:
self.modal.dismiss()
def handle_request(self, request):
self.shortcuts = KeyboardShortcuts({
'ALT+ENTER': self.handle_alt_enter,
'ARROW-UP': self.handle_arrow_up,
'ESC': self.dismiss_modal,
})
self.modal = Modal()
return HTML(
H1('Hello World'),
self.modal,
self.shortcuts,
)
The idea is to add a new component that serves a JavaScript widget that interprets the config given to the KeyboardShortcuts
class (the name is not final), and sends custom input events which get mapped to the configured callbacks on the server.
@SmithChart, @maratori, @grigolet, @laundmo
Looks nice 👍
I really like the idea of handlers for global shortcuts in the frontend.
How would this integrate with a higher-level integration like lona-somethingcss
that would probably like to handle some key presses and a view that would like to handle some others?
@SmithChart: That's a good question, and I am not sure yet. Currently, Lona implements event capturing (handling events from the outer-most node first) only very basic, and I plan on changing this. Every node should have a capture_input_event()
. With that feature in place, use-cases like this should be feasible.
Lately I've been using tailwindcss and daisyui for my UI css. There's some nice css behaviours those libs have to handle visibility etc that seems to get swallowed by lona. This issue isn't about that (I'll post a minimal example later), as a work-around I'd just like to capture key events. Specifically if a modal is displayed and
esc
is pressed, toggle close the modal.My general question is it possible to capture a keypress event and have it sent to the backend?
I've tried
handle_input_event_root
on aLonaView
andhandle_input_event
on aWidget
but that doesn't seem to work unless aTextInput
is involved and focused.I can write a frontend widget to do this (I think) but is there a more
lona
way to achieve this?If I were to generalise the issue even more, is there a way to subscribe to frontend DOM events from the backend? This might be out of scope, but I saw in other issues you talking about v2 so I'm hopeful :)