I have a small Phoenix 1.7 app where I am trying to add a radial progress bar, using the default TailwindUI components: https://tailwindui.com/components
Unfortunately for me, I was only able to find normal progress bars:
https://flowbite.com/docs/components/progress/
Namely:
<div class="w-full bg-gray-200 rounded-full h-2.5 dark:bg-gray-700">
<div class="bg-blue-600 h-2.5 rounded-full" style="width: 45%"></div>
</div>
The only radial progress bar I found was one using DaisyUI:
https://daisyui.com/components/radial-progress/
However, I want to avoid installing anything extra, I really just want to use the default tailwindUI and tailwindCSS that come with Phoenix 1.7
By checking some examples using Tailwind with Apline.js I was able to analyze the code and create a component that does exactly what I want.
This code uses only Phoniex LiveView vanilla, no extra CSS no extra anything !
core_components
:
@doc """
Renders a progress bar for an ongoing operation.
## Examples
<.progress_bar hidden=false progress=15 />
<.progress_bar hidden=false progress=20 message="Activating system ..." />
<.progress_bar hidden=false class="cool-bar" />
"""
attr :hidden, :boolean, default: true, doc: "whether or not to show the progress bar"
attr :progress, :integer, default: 0, doc: "the current progress of the bar"
attr :message, :string, default: "Operation in progress ...", doc: "the message to show while the bar is progressing"
attr :class, :string, default: nil
def progress_bar(assigns) do
assigns = assign(assigns, :circumference, 2 * 22 / 7 * 120)
assigns = assign(assigns, :offset, assigns.circumference - assigns.progress / 100 * assigns.circumference)
~H"""
<div class={@class} hidden={@hidden}>
<div class="flex items-center justify-center">
<p class="text-lg font-semibold"><%= @message %></p>
</div>
<div class="flex items-center justify-center">
<svg class="transform -rotate-90 w-72 h-72">
<circle cx="145" cy="145" r="120" stroke-width="30" fill="transparent" class="stroke-gray-700" />
<circle cx="145" cy="145" r="120" stroke-width="30" fill="transparent"
stroke-dasharray={@circumference}
stroke-dashoffset={@offset}
class="stroke-indigo-500" />
</svg>
<span class="absolute text-5xl stroke-black"><%= @progress %></span>
</div>
</div>
"""
end
Usage in my_app_live.heex.html
:
<div class="min-h-full max-w-full mx-auto py-6 sm:px-6 lg:px-8">
<.progress_bar hidden={false} progress={40} message="Activating system ..." />
</div>
Will produce the following:
For more information on how I created this, feel free to check the whole story on the elixir's forum thread:
https://elixirforum.com/t/radial-progress-bar-using-tailwinui/58098/10?u=fl4m3ph03n1x