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?

Showing Posts 1 to 10

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

itzmidinesh
Hi all, I’m working on a Phoenix project where I need to make external HTTP requests and I’m trying to choose between Req and HTTPoison....
New
yarrichar
I’m very new to Elixir, so sorry if this is a silly question: I am wondering what happens to the mailbox of a process when the machine i...
New
pragdave
How do I tell Hologram not to escape HTML when substituting into templates? {Textile.render(@product.long_description)} escapes the HTM...
New
Fl4m3Ph03n1x
Background When trying to execute mix release on a Windows 11 machine for a Phoenix project I get the following error: * assembling mark...
New
rlipscombe
I’d like to create a file with 600 permissions (rw-------), but there’s a race condition if I create it and then change the permissions. ...
New
saleyn
Is there a way to import record definitions in the iex shell for pretty printing (similar to the rr command in the erl shell)? This woul...
New
rlipscombe
When I use Mix.install with a git dependency, using git@github.com:... how do I change the SSH identity used? I’ve got two Github accoun...
New

Other Trending Topics Top

dominicletz
Hey there, I haven’t seen a list of useful Elixir specific skills for the popular AI tools yet so I’m starting one here with my first. ...
New
raa-ziq
Hi everyone :waving_hand: I wanted to share something I’ve been building — NowBlind, a random chat app designed to help people discover ...
New
mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
OndrejValenta
(I just needed to vent somewhere and LinkedIn is full of hope, or hype, I’m not sure which exactly) AI dream has many faces, but general...
New
kip
Localize is the next generation localisation library for Elixir. Think of it as ex_cldr version 3.0. The first version will be released ...
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

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews