humbleui

Quest 2023-03-17T19:45:28.432519Z

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.

Quest 2023-03-24T20:09:09.485899Z

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

Quest 2023-03-23T18:08:48.686799Z

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

Niki 2023-03-23T19:16:32.775919Z

All event handlers happen on UI thread, there’s now way to hold it for too long

Niki 2023-03-23T19:16:56.488549Z

I’ll take a look if yoy can open an issue

👍 1
Quest 2023-03-23T19:18:11.814219Z

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

Niki 2023-03-23T19:19:03.635209Z

that’s probably focus issue because text field is recreated by dynamic. I still have to figure it out

Niki 2023-03-23T19:19:57.663799Z

Try creating text input outside

Quest 2023-03-23T19:20:21.940729Z

It does work outside -- did a few repros with the only difference being the wrapping dynamic. It's almost certainly the cause

Quest 2023-03-23T19:20:45.165739Z

I'm interested in rewriting these to play nice together. Have any notes you'd want to bring up?

Niki 2023-03-23T19:34:53.510879Z

I wish it was so simple. I’m afraid to solve this properly you’ll need to replace dynamic with smth better

🤔 1
Niki 2023-03-23T19:35:48.455769Z

There might be an easier fix right now, probably in focus-controller somewhere. I bet your issue is that text-field loses focus

Niki 2023-03-23T19:36:27.263849Z

What I meant: try creating it outside (as a value) but then use that value inside dynamic

💯 1
Niki 2023-03-23T19:36:37.904749Z

I understand it won’t always work

Niki 2023-03-23T19:36:50.458459Z

But might be possible in your case

Quest 2023-03-23T20:22:37.346739Z

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

Quest 2023-03-24T01:06:05.927369Z

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

👍 1
Niki 2023-03-20T12:49:58.328569Z

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

Quest 2023-03-20T17:43:43.235229Z

Returning nil fixed my UI with just a few characters. Thanks & I'll comb through the src a little more this week 👀