Mix.install([
{:kino, "~> 0.14"},
{:kino_progress_bar, github: "acalejos/kino_progress_bar"}
])
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])
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])