Phx_component_helpers - Extensible live_components, without boilerplate

Hey there :wave:

A few days ago I extracted a lot of functions I’m using in 2 different projects (one large phoenix LiveView project and a small PETAL app)

It basically answers to the following needs:

  • quickly package UI code into live_components
  • make components extensible from the templates (in the spirit of Tailwind & Alpine)
  • less boilerplate possible.

I first tried Surface, and even if I was impressed, it felt too heavy for me (btw it has more line of codes than LiveView itself) and I’d really prefer to stay closer to the underlying library (LiveView)

Let me know what you think of this lib :hugs:

9 Likes

0.7.0 just landed with improved support for form errors

1 Like

0.8.0 :rocket:

I’m still (I guess) the sole user of this library, but for whatever reason I’m polishing it as if it were to be used by thousands :sweat_smile:

8 Likes

Just released 0.9.0 with new forward_assign/2 that will help writing nested components (you often need to propagate part of assigns to a child component)

Feature-wise there is now everything I wanted in this library.
It just needs a bit more example & documentation before a proper 1.0 release

4 Likes

Pas mal tout ça. :call_me_hand:

I have a form I need to refactor and I might give it a shot while testing your library.
Thanks for continuing working on it and giving us heads-up, I missed the other announcements.

2 Likes

Thank you @crova !
I will actually provide a form code sample very soon. I will post here as soon as it is published!

3 Likes

A glimpse of some of the components we’re writing with phx_component_helpers :eyes:
A table with infinite scroll, sticky headers, sorting, filtering, placeholder, result counter … coming for really cheap to our front-end developpers :slight_smile:

Code source is really neat with proper component encapsulation :ok_hand:

10 Likes

Really good work! Is it the alpine js keeping the left hand side of the page static where the right hand side updates only?

1 Like

No alpine there: only using plain JS (there is actually a single 50 loc JS file for the infinite scroll hook).

The static sidebar on the left is part of the layout, no special trick here, LiveView doesn’t know anything about the layout.

We also use Turbolinks to manage page to page navigation.

3 Likes

As we started to get an ever growing list of components and were also looking to get stronger UI guidelines (I’m looking at you Tailwind colors :eyes:) we built our own storybook (inspired from React’s)

Here is a preview:

9 Likes

Liveview storybook is super interesting to us. We have a LOT of components.

2 Likes

Do you use Surface or basic Livecomponents?

I work with @cblavier, we only use Livecomponents.

Is this three column template shell(icons menu column, Admin sub-menu column, content column) a custom one or something we can find somewhere?

Glad you like it, but it’s custom markup / CSS.
If you’re interested, here is the mobile responsive version : CleanShot 2021-04-26 at 14.07.12 · CleanShot Cloud

1 Like

Thanks for this table sample. I was wondering how to handle the headers of a table and you gave me some good pointers.
I had mentioned a form refactor to dig a bit on your library but decided to start with a table. Seemed less complicated.

Don’t be shy on the examples when you get time, they sure help understanding how to properly use the library!

edit: @cblavier Sorry to ping you but I wanted to check something before going hammer here:
Am I’m right in assuming that your are passing the headers: [id: "ID", ...] as a normal assign with Map.put(assigns, :headers, assigns.headers) and not with any kind of helper function you provide within the library?
Something like:

def update(assigns, socket) do
      assigns =
        assigns
        |> extend_class("some-class")
        |> Map.put(:headers, assigns.headers)
  
     {:ok, assign(socket, assigns)}
  end

And then in your render/1 you do a comprehension with for {k, v} <- assigns.headers do?

Did I get it right?

And if this is the case, any reason you’re doing your headers with a keyword list instead of a simple list?

3 Likes

Ok :slight_smile:

Knowing that someone (else than me) is using the library cheers me up, so I’ll write some working examples of table components.

I’ll let you know in this thread when ready (this week I guess)

1 Like

No worries.
If I manage to get things right here I would gladly help you with some examples if you’d like.

2 Likes

I was not aware of what was storybook, but now I am :slight_smile:

So, the question now his if your storybook is something that will be public available to test all live components that you and others release/build?

1 Like

If some people here are interested, yes we might indeed open-source this live_components storybook in a foreseeable future.

But like the original storybook, it would be an empty shell that you’ll be able to fill with your own components. The components we’re developing, even if somewhat generic, are really closely fitting to our business needs.

1 Like

I really like the storybook concept thus I would like to see it public if possible.

I started a library like yours only for my personal projects, but each time I see one of your posts here I think in making the switch, and now this storybook is really enticing me :slight_smile:

2 Likes