I needed to reuse React components from my Chrome extension in my Phoenix/LiveView backend. I noticed that for Svelte/Vue, there are live_vue and live_svelte . So, I created the equivalent in React, live_react:
Here is a small demo on Fly: demo .
I have not yet implemented SSR, slots, sigil, and the macro to generate components.
13 Likes
Great work! I do wonder if there is some kind of shared abstraction these libraries could build on - if there was something like live_vite or live_frontend, or something like that, then have adaptors for each FE framework.
4 Likes
The LOC of each library is quite short but specific to Vite, Svelte, React.
Builder
JS Prod
live_svelte
Custom esbuild
none
live_vue
vite
vue
live_react
hex esbuild
react, react-dom
Have a look at the hooks.js of each
import { createApp, createSSRApp, reactive, h } from 'vue'
import { liveInjectKey } from "./use"
import { normalizeComponents, getComponent } from './components';
function mapValues(object, cb) {
return Object.entries(object).reduce((acc, [key, value]) => {
acc[key] = cb(value, key, object);
return acc;
}, {});
}
function getAttributeJson(el, attributeName) {
const data = el.getAttribute(attributeName)
return data ? JSON.parse(data) : {}
}
function getSlots(el) {
const dataSlots = getAttributeJson(el, "data-slots")
return mapValues(
This file has been truncated. show original
import {normalizeComponents} from "./utils"
function getAttributeJson(ref, attributeName) {
const data = ref.el.getAttribute(attributeName)
return data ? JSON.parse(data) : {}
}
function detach(node) {
node.parentNode?.removeChild(node)
}
function insert(target, node, anchor) {
target.insertBefore(node, anchor || null)
}
function noop() {}
function getSlots(ref) {
const slots = {}
This file has been truncated. show original
import React from "react";
import ReactDOM from "react-dom/client";
function getAttributeJson(el, attributeName) {
const data = el.getAttribute(attributeName);
return data ? JSON.parse(data) : {};
}
function getProps(hook) {
return {
...getAttributeJson(hook.el, "data-props"),
// pass the hook callbacks to the component
pushEvent: hook.pushEvent.bind(hook),
pushEventTo: hook.pushEventTo.bind(hook),
handleEvent: hook.handleEvent.bind(hook),
upload: hook.upload.bind(hook),
uploadTo: hook.uploadTo.bind(hook),
};
}
This file has been truncated. show original
3 Likes
orion
July 7, 2024, 6:43pm
4
Great work! Thank you for live_react!
I’m not sure if it’s what @johnknott had in mind but have you looked at Komodo?
Hi there!
I’ve created a small library, Komodo , that allows easy use of JS framework components from Phoenix LiveView.
Each framework just needs a small piece of easy-to-write Javascript adapter code to work with it (this is already provided for React, Svelte, Vue and Web Components).
[komodo-short]
Rationale
There are a few libraries already out there for rendering JS components (for React, Svelte, etc.) from LiveView, however I personally wanted a few things which they all seemed to be mis…
3 Likes
MRdotB
September 10, 2024, 3:46pm
5
live_react has been picking up interest, as seen in projects like PhoenixAnalytics . Inspired by the Server-Side Rendering (SSR) features in live_svelte
and live_vue
, I’ve implemented it for live_react
.
I released a 0.2.0-beta
and will release 0.2.0
when I’m confident the SSR feature is production ready.
ssr demo
7 Likes