livebook-dev / kino

Client-driven interactive widgets for Livebook
Apache License 2.0
362 stars 60 forks source link

Rerender an input will make it losing focus #386

Closed cinoss closed 7 months ago

cinoss commented 7 months ago

If we have a separate frame/form to render input only once, debounce behavior works really nicely. But if we want to have input and other things stay in one frame, interval debounce would trigger render and make input losing focus mid-typing.

Untitled notebook

Mix.install([
  {:kino, "~> 0.12.3"}
])

Section

input = Kino.Input.number("Counter", debounce: 200)

frame = Kino.Frame.new()

render = fn current ->
  frame
  |> Kino.Frame.render(
    Kino.Layout.grid(
      [
        input,
        Kino.Markdown.new("""
        # #{current}
        """)
      ],
      columns: 2
    )
  )
end

render.(0)

frame
render.(Kino.Input.read(input))

[input: input]
|> Kino.Control.tagged_stream()
|> Kino.listen(fn {_tag, payload} = event ->
  event |> dbg
  render.(payload.value)
end)

Kino.nothing()
jonatanklosko commented 7 months ago

Yeah, each rendering gets separate elements. Instead of having frame(grid(input, markdown)), you can do grid(input, frame(markdown)), so that you only re-render the content that changes.