The goal of LiveElements is to improve the ergonomics of integrating custom HTML elements with Phoenix LiveView.
This project assumes you are using custom elements on a page served by phoenix. If you are building custom elements that need to talk to a phoenix app but live on a page not served by phoenix (on a statically generated site for example), you may want to check out LiveState instead.
We accomplish our goal by creating helper functions to make working with custom elements just as easy as any other LiveView functional component.
For example, let's say you have a <todo-list>
custom element that has an attribute
that takes a list of todos, and emits an add_todo
Custom Event. LiveElements will
generate a helper function (details below) which will wrap the custom element like
so:
<.todo_list todos={@todos}></.todo_list>
Serialization of todos to json happens automatically. In your live view you handle the add_todo
event just like any other live view event:
def handle_event("add_todo", %{"todo" => todo}, %{assigns: %{todos: todos}} = socket) do
{:noreply, socket |> assign(todos: todos ++ [todo])}
end
If available in Hex, the package can be installed
by adding live_elements
to your list of dependencies in mix.exs
:
def deps do
[
{:live_elements, "~> 0.2.1"}
]
end
Presuming your custom element emits custom events you want to handle in live view, you'll need to install the phoenix-custom-event-hook
npm package and add the hook
to the live socket.
To install (from project dir):
npm install --prefix assets phoenix-custom-event-hook
Then, in app.js
(or wherever you set up your live socket):
import PhoenixCustomEventHook from 'phoenix-custom-event-hook';
let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}, hooks: {PhoenixCustomEventHook}})
In the LiveViews where you want to call custom element helper functions do:
use LiveElements.CustomElementsHelpers
This will add helper functions for any custom elements found in your manifest file, if
you have one configured, as well as importing the custom_element
macro.
LiveElements can consume a custom elements manifest file to produce helper functions at compile time. To do so, in your config:
config :live_elements,
custom_elements_manifest: Path.expand("../assets/custom-elements.json", __DIR__)
To produce a manifest file automatically from your custom element source code, you might want to check out the custom element analyzer from open-wc.org.
If you are using a library that does not have a manifest, or don't wish to use one, you can
also use the custom_element
macro like so:
custom_element :bx_data_table, events: ["bx-table-header-cell-sort"]
This would then allow you to call <.bx_data_table>
in your live view and handle_event("bx-table-header-cell-sort", ...)
to respond to events.
The live_elements_testbed contains an example phoenix liveview app demonstrating all of the features of live_elements, as well as integration tests for the live_elements project.