Fl4m3Ph03n1x

Fl4m3Ph03n1x

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?

First 10 of 10 Posts Switch mode

Fl4m3Ph03n1x

Fl4m3Ph03n1x OP

I did try something similar before, unfortunately, I get the following error in my heex file:

code:

<div
      x-data="scrollProgress"
      class="fixed inline-flex items-center justify-center overflow-hidden rounded-full bottom-5 left-5"
    >
      <!-- Building a Progress Ring: https://css-tricks.com/building-progress-ring-quickly/ -->
      <svg class="w-20 h-20">
        <circle
          class="text-gray-300"
          stroke-width="5"
          stroke="currentColor"
          fill="transparent"
          r="30"
          cx="40"
          cy="40"
        />
        <circle
          class="text-blue-600"
          stroke-width="5"
          :stroke-dasharray="circumference"
          :stroke-dashoffset="circumference - percent / 100 * circumference"
          stroke-linecap="round"
          stroke="currentColor"
          fill="transparent"
          r="30"
          cx="40"
          cy="40"
        />
      </svg>
      <span class="absolute text-xl text-blue-700" x-text="`${percent}%`"></span>
    </div>

error

== Compilation error in file lib/web_interface/live/activate_live.ex ==
** (Phoenix.LiveView.Tokenizer.ParseError) lib/web_interface/live/activate_live.html.heex:22:11: unsupported attribute ":stroke-dasharray" in tags
   |
19 |         <circle
20 |           class="text-blue-600"
21 |           stroke-width="5"
22 |           :stroke-dasharray="circumference"
   |           ^
    (phoenix_live_view 0.18.18) lib/phoenix_live_view/tag_engine.ex:1383: Phoenix.LiveView.TagEngine.raise_syntax_error!/3
    (phoenix_live_view 0.18.18) lib/phoenix_live_view/tag_engine.ex:656: Phoenix.LiveView.TagEngine.handle_token/2
    (elixir 1.15.4) lib/enum.ex:2510: Enum."-reduce/3-lists^foldl/2-0-"/3
    (phoenix_live_view 0.18.18) lib/phoenix_live_view/tag_engine.ex:182: Phoenix.LiveView.TagEngine.handle_body/1
    (phoenix_live_view 0.18.18) expanding macro: Phoenix.LiveView.HTMLEngine.compile/1
    lib/web_interface/live/activate_live.html.heex:1: WebInterface.ActivateLive.render/1
    (phoenix_live_view 0.18.18) c:/Users/pedro/Documents/market_manager/apps/web_interface/lib/web_interface/live/activate_live.ex:1: Phoenix.LiveView.Renderer.__before_compile__/1
LostKobrakai

LostKobrakai

Use of invalid html attributes is not allowed in heex. You can use the longer x-bind:… format.

Fl4m3Ph03n1x

Fl4m3Ph03n1x OP

That’s fair, but thus far I was not able to find an example that does not use such attributes.

What is it and what does it do? I was not able to find anything in the docs about it:

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.

Fl4m3Ph03n1x

Fl4m3Ph03n1x OP

I am unsure on how the Tailwind package and Apline.js are connected:

https://github.com/phoenixframework/tailwind

Clearly i am looking in the wrong place. Do Phoenix 1.7 applications now also use AlpineJS by default?

LostKobrakai

LostKobrakai

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

outlog

outlog

apologies for posting a link that depends on alpine.. I believe it’s best avoided nowadays with all the liveviewjs improvements..

think you need to go with this underlying example Building a Progress Ring, Quickly | CSS-Tricks - and then maybe take some tailwind styling from the alpine dependent one..

Fl4m3Ph03n1x

Fl4m3Ph03n1x OP

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!

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)

— All posts loaded —

Where Next? Top

Trending in Questions Top

stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New
jonnycharles
I’m in search of an Elixir library that offers PDF generation capabilities similar to Ruby’s Prawn. While there have been discussions abo...
New
spammy
I’m looking to build a personal workflow to quickly deploy web applications written in elixir/phoenix, for local consumption (ie not on t...
New
dli
Before I dive in myself, did anyone successfully sprinkle Hologram into their existing LiveView app? Looking for hints regarding: Addi...
New
roeland
Kia ora, We have been using elixir-google-api to connect to Google Drive. However, with the updates to Tesla due to CVEs this is now bro...
New
bottlenecked
Hi all, I wanted to ask how the community is dealing with post-release steps. Today we have Ecto migrations, which make sure that the db...
New
rahultumpala
Hello, I have an Elixir backend that implements a custom protocol over TCP. I want to load test the backend and assess the performance o...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
ausimian
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New
juhalehtonen
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New

We're in Beta

About us Mission Statement