fceruti

fceruti

Surface Boxicon - a component library that wraps the boxicons library (My first library :))

Hey everyone!

For a personal project I’m working, I need to use boxicons in surface templates. Since the package didn’t exist, I decided to take the matter into my own hands. The results are here:

https://github.com/fceruti/surface-boxicon

I feel like a leveled up or something.

PS: The library is very small, so I’d very happy if you could check it out and point out things you would have don’t better. Anything. Even style pointers are most welcomed.

Most Liked

msaraiva

msaraiva

Broadway Core Team

Hi @fceruti. Nice work!

One thing to keep in mind is that defining modules is more expensive than defining multiple function clauses so since all components have the same props, I believe you would have a more consistent API, along with faster compilation, if you define a single component with name and maybe also a type prop to differentiate each icon. Something like:

def render(%{name: "video-plus", type="solid"} = assigns) do
  ~F[<svg ... width={@size} height={@size} class={@class} .../></svg>]
end

def render(%{name: "video-plus", type="regular"} = assigns) do
  ~F[<svg ... width={@size} height={@size} class={@class} .../></svg>]
end

def render(%{name: "bell", type="solid"} = assigns) do
  ~F[<svg ... width={@size} height={@size} class={@class} .../></svg>]
end

def render(%{name: "bell", type="regular"} = assigns) do
  ~F[<svg ... width={@size} height={@size} class={@class} .../></svg>]
end
...

Then you could use it like:

<BoxIcon name="bell" type="solid"/>
fceruti

fceruti

OK, so I managed to both finished the book and the library :partying_face:

I added a way to load less functions using configuration

config :surface_boxicon,
  icons: [
    regular: ["calendar", "chvron-down"],
    solid: ["hand", "file-md"],
    logos: ["docker"]
  ]

But it turned out to be completely unnecessary, the Module is compiling super fast with all the icons. The current Boxicon module looks like this:

defmodule Boxicon
  ...

  def render(assigns) do
    ~F[<svg xmlns="http://www.w3.org/2000/svg" width={"#{@size}"} height={"#{@size}"} class={"#{@class}"} viewBox="0 0 24 24">{render_content(@type, @name)}</svg>]
  end

  for %Boxicon.Source{type: type, name: name, content: content} <- @icons do
    defp render_content(unquote(Atom.to_string(type)), unquote(name)),
      do: unquote(Phoenix.HTML.raw(content))
  end

  defp render_content(_, _), do: ""

end

I’m not sure why this is the case, but maybe the compiler is having an easier time dealing with string signatures instead of maps. If I create one render function per icon, pattern matching on the assigns map, I go back to lousy compile times.

fceruti

fceruti

Since this thread was first published, I migrated my code from Surface to vanilla LiveView.

Here is a new package for everyone using heex files: Boxicons Heex

I think the API to use it, it’s pretty clever:

      <Box.icons
        type="regular"
        name="calendar"  
        size="64" 
        class="icon green"
      />

Have a nice day!

PS: It’s updated to use boxicons 2.1.1

Where Next?

Popular in Announcing Top

alisinabh
Hey everyone i’ve developed a library for Jalaali calendar for elixir which supports converting Gregorian dates to Jalaali and vice vers...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 54006 488
New
jakub-zawislak
Hi everyone, I’m coming from the Symfony (PHP) framework. I like Phoenix, but it has a one thing that was build much better in the Symfo...
New
mathieuprog
Hello :waving_hand: Allow me to introduce you to Tz, an alternative time zone database support to Tzdata. Why another library? First a...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
benlime
LiveMotion enables high performance animations declared on the server and run on the client. As a follow up to my previous thread A libr...
New
MRdotB
I needed to reuse React components from my Chrome extension in my Phoenix/LiveView backend. I noticed that for Svelte/Vue, there are live...
New

Other popular topics Top

rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
dogweather
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something… Haskell reminds me of Java, and e...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New

We're in Beta

About us Mission Statement