Surface - A component-based library for Phoenix LiveView

Thanks for creating this example.

Your demo looks good but too improve it you can use highlight.js for your code snippets

Thanks - I have added highlight.js now :slight_smile:

1 Like

Glad I could help @joerichsen

Awesome! Iā€™ll add it to the ā€œComponentsā€ section next time I update the demo.

Thanks!

1 Like

thanks for this detailed explanation. Iā€™ll admit that I, too, was too dense to understand the advantages, but I think I do now. I used to manage some programmers who were programming in react and also had to write react code myself, but didnā€™t have a full understanding of why itā€™s so good beyond ā€˜itā€™s functional and state management is saneā€™ so thanks for explaining react better than react does =D

Only when support for this was coded. Remember that not everybody will use the same editor as you so it can look differently in different editors. Vim for example do not support that AFAIK.

Also not everyone is using syntax highlighting (for example visually impaired people).

But it can happen, for multiple of reasons:

  • simpler transition
  • inexperienced developer
  • creation of new HTML tag by the w3c in the future
2 Likes

@hauleth thanks for pointing those exceptions. Itā€™s important that people have them in mind before adopting any technology. As I said before, there is always a tradeoff.

Vim does not support it yet. If nobody out there with the required skills to add syntax highlighting for vim gets interested in this library, that probably means that the library itself itā€™s not as useful as I thought. So if that happens, itā€™s probably a sign that I should move on and try something else.

Indeed. All of those things could happen. However, they can happen in any technology using the concept of ā€œcomponentsā€, including React, Vue, Svelte or any other that embraced a similar approach. As far as I know, that hasnā€™t been a problem for the adoption of those technologies. Those are really minor issues, IMO.

Lastly and probably the most important thing out of this discussion is that it helped me a lot to convince myself that weā€™ve chosen a good approach. Why? Because since Surface knows the structure of the code, we can easily add an option to the translator to check if a component has the same name of an existing HTML element and present a proper warning (or error) to the user.

See how powerful the abstraction is? Even some of the downsides of it can be properly handled in a way that guides the user to do the right thing. I think itā€™s just fantastic that we can do that, especially for the inexperienced developers you mentioned.

6 Likes

Awesome library! I was already making some live components using Bulma (with inspiration from the excellent Buefy) and this will make the templating/props experience almost like React!

Quick questionā€¦ I was reading this issue and is it true Surface.Component can be used to make standard stateless functional templates without LiveView being installed at all?? I just assumed Surface was completely coupled to LV but it would be awesome to be able to use it in my non-LV projects also.

3 Likes

My initial intention for Surface.Component was to keep it as a sort of functional component that could work in both, LV and non-LV projects. The problem is that currently, LiveView does not allow nesting live components inside a functional component. A phoenix LiveComponent can only be initialized inside a LiveView or in other LiveComponent. So in order to allow nested components to work properly in LV Iā€™m changing the implementation of Surface.Component to also rely on live_component/3 which will, unfortunately, make it incompatible with non-LV projects.

BTW, I also think it would be great to be able to use the same model in non-LV projects. However, since weā€™re currently focusing on LV, I think itā€™s better to remove the support for now. If in the future more people get interested in using Surface in non-LV projects, we can try to talk to the phoenix core team again and see if we can find an alternative solution for the problem.

2 Likes

Thatā€™d be awesome! Iā€™m using Bulma currently and built up an internal livecomponent like library using macros but livecomponents would be so much nicer. Still even as macros, a component library makes developing new pages a sinch. Iā€™m excited to look into your library!

Do you wrap things like dropdowns/number selects/etc and handle their events? If thereā€™s a way to add Bulma based live-components Iā€™d take a look at that (rather than building my own).

It sounds like you are assuming that ā€œeveryoneā€ is using VSCode, but many more editors exist, and each editor have many different themes you can choose from.

So his assumption is perfectly valid in thinking that itā€™s a typo, and he will not be alone for the many years to come, but I am not saying you should rename them.

And congrats for the great work and effort your are putting on this project :slight_smile:

1 Like

This sounds like it should be done now, then rather later on, when it may require a lot of changes, or even make it non viable due to backwards incompatibilities and design decisions.

Bummer! Would be great if we could somehow use it on non-LV projects without requiring significant work on core LV. Is there a way to make a new component type like Surface.StaticComponent or something with the current behaviour that doesnā€™t depend on LiveView?

Just hoping there is an easy way to support this because I much prefer the benefits of using this (so eloquently laid out in your earlier reply) versus EEx in non-LV projects.

You have to pick your battles. Trying to decouple early on will slow down development to accommodate a small fraction of users, so punting on this is something that Iā€™d continue to kick down the road.

1 Like

I see this more as a design choice that can hurt down the road, then a question of decoupling code, but I donā€™t know the code as well as you :wink:

Are you really sure that is a small fractions of users? Seems that you are over confident that ā€œeveryoneā€ will be using LiveView in their projects?

Sorry, I didnā€™t mean for it to come across that way. Speaking from experience, folks very often push for maintainers to decouple too early in projects, and it almost always is the wrong call. You can get lost in the weeds way too early instead of making forward progress to 1.0. For now, Iā€™d focus on getting the surface model and features intact for its intended purpose.

4 Likes

I know that you havenā€™t said it with that intention, thatā€™s why I used ā€œeveryoneā€ between commas :wink:

Since Iā€™m still working on the core features, I didnā€™t have time to build a full suite of components yet. However, all examples in my demo were created using Bulma, including a live Dialog component that handles events. As far as I know, thereā€™s also a WIP by @joerichsen using bootstrap.

I understand your concern but I have to agree with @chrismccord on this one. The problem is that having too many different kinds of components at this moment will certainly slow me down. My main goal now is to validate the model in the most complex scenario, which is using stateful components with LV. If everything works as expected, adding a simpler version for non-LV projects will be a breeze, trust me :slight_smile:

Iā€™ll definitely come back to this discussion as soon as I finish Implement a compiler instead of a translator Ā· Issue #15 Ā· surface-ui/surface Ā· GitHub. If until then we have no solution on the LV side and we find out that a lot of people want this feature, Iā€™ll consider creating a new separate Surface.StaticComponent as suggested by @tme_317.

8 Likes

is there a way to render a component in a .leex template? I am looking to add a Live Layout, and I believe that means I need to point to a leex file, but if possible I would like to reuse some Surface components in that template. I have tried <%= live_component @socket, MyComponent %> but it appears it is missing some preparation (the :surface value).

Hi @regal!

Currently, surface components require some preparation as you noticed. I opened this issue to create a surface_component/3 wrapper that could replace live_component/3 for those cases.

I have a quick question though. Would you still use a .leex file if you could load a .sface file that accepts the surfaceā€™s syntax instead? The .sface proposal is described here. Iā€™m trying to list a few possible scenarios where this feature would be useful before start working on it.

Cheers.

2 Likes