Fl4m3Ph03n1x

Fl4m3Ph03n1x

Radial progress bar using TailwinUI

Background

I have a small Phoenix 1.7 app where I am trying to add a radial progress bar, using the default TailwindUI components: Tailwind CSS Components - Tailwind Plus

Unfortunately for me, I was only able to find normal progress bars:

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:

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

Questions

  1. Does someone know how to create a a radial progress bar component using the default setup that comes with Phoenix LiveView 1.7?
  2. Am I missing some component that already does this?

Marked As Solved

Fl4m3Ph03n1x

Fl4m3Ph03n1x

No need to apologize !
Even though the link and code you shared used alpine, it was still very educative. I was able to analyze the code and create a component that does exactly what I want. Its also quite pretty, so I am very proud. This code uses only Phoniex LV 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:

Possible improvements

Currently i am not sure if there is a more elixir way of updating the assigns:

assigns = assign(assigns, :circumference, 2 * 22 / 7 * 120)
assigns = assign(assigns, :offset, assigns.circumference - assigns.progress / 100 * assigns.circumference)

But other than that, I am pretty happy with it.

Additional info

For those of you curious, you can also check this other solution someone else provided in SO:

I hope this helps!

Also Liked

dfalling

dfalling

You can compute this circumference outside of the function since it’s never changing.

Eg

# 2 * 22 / 7 * 120
@circumference 754.285714285714286

(not sure how important precision is for that variable)

LostKobrakai

LostKobrakai

I mean sure if you’re looking at the LV docs and not the Alpine docs. :attr is a short form for x-bind:attr in alpine.

LostKobrakai

LostKobrakai

No. Not sure where you got that html you posted, but it’s using alpine.

Last Post!

dfalling

dfalling

You can compute this circumference outside of the function since it’s never changing.

Eg

# 2 * 22 / 7 * 120
@circumference 754.285714285714286

(not sure how important precision is for that variable)

Where Next?

Popular in Questions Top

vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New

Other popular topics Top

nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 54921 245
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New

We're in Beta

About us Mission Statement