Skip to content

Instantly share code, notes, and snippets.

@hugobarauna
Last active September 18, 2024 16:42
Show Gist options
  • Save hugobarauna/2eee6ed4a4b21c5e0957da190f4dad2d to your computer and use it in GitHub Desktop.
Save hugobarauna/2eee6ed4a4b21c5e0957da190f4dad2d to your computer and use it in GitHub Desktop.
How to display progress using Kino

How to display progress

Mix.install([
  {:kino, "~> 0.14"},
  {:kino_progress_bar, github: "acalejos/kino_progress_bar"}
])

Using a custom a spinner based on on Kino.HTML

defmodule KinoSpinner do
  def new(dimensions \\ "30px") do
    Kino.HTML.new("""
    <div class="loader"></div>

    <style>
      .loader {
        border: 16px solid #f3f3f3; /* Light grey */
        border-top: 16px solid #3498db; /* Blue */
        border-radius: 50%;
        width: #{dimensions};
        height: #{dimensions};
        animation: spin 2s linear infinite;
      }

      @keyframes spin {
        0% { transform: rotate(0deg); }
        100% { transform: rotate(360deg); }
      }
    </style>
    """)
  end
end
Kino.Layout.grid(
  [KinoSpinner.new(), KinoSpinner.new("15px"), KinoSpinner.new("40px"), KinoSpinner.new("50px")],
  columns: 2
)
import Kino.Shorts

How we can use that KinoSpinner with a form:

form =
  Kino.Control.form(
    [
      name: Kino.Input.text("Data", default: "some data to process")
    ],
    submit: "Submit"
  )

output_frame = frame()

Kino.listen(form, fn _event ->
  Kino.Frame.render(output_frame, grid([text("Processing..."), KinoSpinner.new()]))
  Process.sleep(2_000)
  Kino.Frame.render(output_frame, "Processing is done. ✅")
end)

grid([form, output_frame])

Using a progress bar custom Kino

form =
  Kino.Control.form(
    [
      name: Kino.Input.text("Data", default: "some data to process")
    ],
    submit: "Submit"
  )

output_frame = frame()

Kino.listen(form, fn _event ->
  progress_bar = KinoProgressBar.new(max: 100)
  Kino.Frame.render(output_frame, progress_bar)
  Enum.each(1..100, fn index -> 
    KinoProgressBar.update(progress_bar, index, 100)
    Process.sleep(50)
  end)
  Kino.Frame.render(output_frame, "Processing is done. ✅")
end)

grid([form, output_frame])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment