This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-03-17
Channels
- # announcements (6)
- # babashka-sci-dev (6)
- # beginners (99)
- # biff (3)
- # cider (4)
- # clerk (44)
- # clj-kondo (2)
- # clojure (65)
- # clojure-europe (57)
- # clojure-germany (5)
- # clojure-nl (1)
- # clojure-norway (13)
- # clojure-spec (19)
- # clojure-uk (3)
- # clojurescript (8)
- # conjure (3)
- # cursive (21)
- # datahike (19)
- # datomic (1)
- # events (7)
- # fulcro (14)
- # graalvm (3)
- # gratitude (1)
- # guix (5)
- # honeysql (1)
- # humbleui (19)
- # hyperfiddle (39)
- # lsp (4)
- # malli (7)
- # music (1)
- # off-topic (33)
- # pathom (65)
- # re-frame (9)
- # reagent (3)
- # reitit (6)
- # releases (1)
- # sql (15)
- # tools-build (7)
- # vim (5)
- # xtdb (16)
In response to a bug I found, I'm considering how to write a library option to enable the behavior of "text-input ignoring certain keys."
My exact case is that I want to input text, then press Enter to 'submit' (clear text + invoke a function.) The library currently invokes the parent :enter
callback but also adds an empty newline/enter character to the end of the :text
string, which triggers a UI re-update (and an exception in my bugged case.)
Here's the options I'm considering, & does anyone have any advice or thoughts before I start implementation?
-----------------
A) Implement preventDefault
(ala Elm) as a supported option for the TextInput
class. This would take a seq of keyword 'keys' that should be ignored.
B) Option A might be better implemented as the ability to stop further event propagation as it's "captured" from the parent to child elements? Then a wrapping focusable
or on-key-focused
could handle this.
C) Ignore A/B, extend :on-change
as suggested by Lilactown's example in https://github.com/HumbleUI/HumbleUI/issues/68
(let [*num (atom {:text "23"})]
(ui/text-field
{:on-change #(when (Float/parseFloat %) (swap! *num assoc :text %))}
*num))
This would hypothetically allow :on-change
to override the text-input's default behavior and control all set text. It will require some good refactor, as the current draft impl only invokes :on-change
as a side-effect.Take a look at ui/on-key-focused
The way it works is that if your callback returns truth-y value, the event propagation stops and child never receives it
Returning nil fixed my UI with just a few characters. Thanks & I'll comb through the src
a little more this week 👀
I'm tracking down a bug where events are propagating down to the text-input class even when a higher level :enter
handler returns nil
on the :enter key-event.
In the worst case, :text
still gets updated to include a \r
at the end, but the :line
value gets nil'd and the UI library crashes. It might be that triggering another update to the state during the key-event is causing this, or perhaps from blocking the UI thread for too long.
LMK if you have any pointers on this but otherwise I'll keep going until I can PR a fix
Sure, I'll try to nail down a more exact repro if I can't figure it out myself.
There was one other edge --
text-input
doesn't seem to work inside of a ui/dynamic
block. Higher level focusable
will still trigger a (mouse click) callback, but text-input doesn't respond to any key-events. I haven't gone digging yet but we'll see
that’s probably focus issue because text field is recreated by dynamic. I still have to figure it out
It does work outside -- did a few repros with the only difference being the wrapping dynamic. It's almost certainly the cause
I'm interested in rewriting these to play nice together. Have any notes you'd want to bring up?
I wish it was so simple. I’m afraid to solve this properly you’ll need to replace dynamic with smth better
There might be an easier fix right now, probably in focus-controller somewhere. I bet your issue is that text-field loses focus
What I meant: try creating it outside (as a value) but then use that value inside dynamic
Your theory is correct from tests -- creating text-field in a let
above the dynamic, & then using it inside dynamic works. I see this is already open at Text field inside of dynamic loses focus when re-rendered
- https://github.com/HumbleUI/HumbleUI/issues/50
I originally tried using dynamic
for a wrapping router
component on the state's :main-screen
value. This is a nice pattern that I don't want to giveup, so I'll go looking for the simple fix you alluded to (storing text-field focus in the atom)
You mention eventually replacing dynamic with something more reliable
. I understand if you're too busy for a writeup, but I'd love to know your thoughts here in case I need to try & implement this
Found some success adding key :focused
to the :text-input state & having it set :focused of its wrapping Focusable component. Thanks for the clues -- code appears to work but has some awkward parts. I'll refactor & test more tomorrow
Opened https://github.com/HumbleUI/HumbleUI/pull/71 . My initial commit breaks parent on-key-focus
callbacks though, might be a better way to do this