cvkmohan

cvkmohan

Component Library - Surface or LiveView?

Though Phoenix LiveView borrowed a lot of the great functionality built in Surface by @msaraiva, I do think there is still a very glaring gap. This gap is more pronounced when you intend to build a reusable component library.
At this moment there is still no easy way to bundle Javascript into the Phoenix LiveView components. For example, suppose there is some javascript that you want to execute as a hook, how do you make it into a bundle?
Surface already has this solved via Surface (surface-ui.org). In that sense, if we want to build a really reusable component library ala Chakra UI - A simple, modular and accessible component library that gives you the building blocks you need to build your React applications. - Chakra UI (chakra-ui.com), Surface is more suited to such purpose. It is not yet possible to do it with LiveView.
Is my understanding incorrect? Am I missing anything obvious? Is there a way to ship Javascript also as part of the mix package?

Most Liked

trisolaran

trisolaran

@zachallaun and @LostKobrakai already hinted at this, but I just wanted to spell it out:

It’s actually relatively easy, and you just need to look at phoenix_live_view itself. LiveView needs a JS file to work. So how is it included in your app?

The hex package doubles as npm package by including a package.json that contains the location of the js file, so you can just do import {LiveSocket} from "phoenix_live_view" in the root file of your JS bundle. You can do that because the standard builder is esbuild, which will use your deps folder as the base folder for all dependencies (but will also look into assets so you can add stuff there as well). Things become slightly more complicated if you depart from the esbuild-based process and want to use something like Webpack: in that case you’ll need to add the hex packages as “path dependencies” in your package.json file, as explained here. What sucks about this latter approach is that you have to run a npm install --force after every update of your hex package to get the latest JS into your assets folder.

In LiveSelect I’m simply copying this simple idea :slight_smile:, and this is the best way (that I know of) for a 3rd party library to include its JS dependencies.

On the other hand, what I find really problematic is when my library wants to include some custom CSS. Currently there is no easy and portable way to do it, AFAIK. Esbuild can output css, but some folks (like me) only use tailwind-cli and that would require the user to generate and add a second css file.

mayel

mayel

While it’s been great to see LiveView adopt some of Surface’s goodies, there’s still more:

  • both scoped JS and scoped CSS
  • css_variant option on component props to auto-generate CSS class (i.e. tailwind) variants based on prop values
  • contexts are huge for making certain assigns (eg current_user) available without needed to explicitly pass them to every child component
  • Dynamic.Component and Dynamic.LiveComponent for including components with a dynamic name (eg. configurable widgets)
  • MacroComponent for creating specific components that are rendered at compile time (eg. to process static content like markdown, SVG icons, etc only once)
zachallaun

zachallaun

You can bundle JS with a mix project. Here’s a great project to use as an example: GitHub - maxmarcon/live_select: Dynamic (multi)selection field for LiveView · GitHub

Edit to add: the user does have to include this somehow in their own JS bundle and then export the required hooks, but that’s usually like ~2 lines. See here.

Where Next?

Popular in Discussions Top

blackode
Elixir Upgrading is so Simple in Ubuntu and It worked for me Ubuntu 16.04 git clone https://github.com/elixir-lang/elixir.git cd elixir...
New
AstonJ
I’ve just started the Phoenix part of the utterly brilliant online course by @pragdave. On generating the Phoenix app he uses the --no-ec...
New
crabonature
I’m still quite new to Elixir. As I understand we got in Elixir “multi guards” as convention to simplify one large guard with or’s?: de...
New
tmbb
This is a post to discuss the new Phoenix LiveView functionality. From Chris’s talk, it appears that they generate all HTML on the serve...
342 18272 126
New
AlexMcConnell
The reason that Rails is as popular as it is is because it’s very easy for relatively inexperienced developers to get a lot of work done....
588 19675 166
New
ejpcmac
I have discovered Nix last month and I am currently on my way to migrating to it—both on macOS at home and the full NixOS distrubution at...
New
New
PragTob
Hey everyone, this has been on my mind for some time and I’d love your input on it! TLDR: I feel like maps are superioer for storing and...
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
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

Other popular topics Top

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
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 42158 114
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
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
Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3271 127536 1222
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New

We're in Beta

About us Mission Statement