added solid.js as front end

This commit is contained in:
2026-02-14 16:23:55 -06:00
parent 4970133b83
commit d645bda942
11 changed files with 430 additions and 5 deletions
+2 -1
View File
@@ -26,12 +26,13 @@ import { hooks as colocatedHooks } from "phoenix-colocated/river_connect"
import topbar from "../vendor/topbar"
import { AudioRecorder } from "./hooks/audio_recorder"
import { SolidBridge } from "./hooks/SolidBridge"
const csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
const liveSocket = new LiveSocket("/live", Socket, {
longPollFallbackMs: 2500,
params: { _csrf_token: csrfToken },
hooks: { ...colocatedHooks, AudioRecorder },
hooks: { ...colocatedHooks, AudioRecorder, SolidBridge },
})
// Show progress bar on live navigation and form submits
@@ -0,0 +1,47 @@
import { createSignal } from "solid-js";
export function SolidApp(props) {
// Local state for optimistic updates or other UI-only logic
const [isUpdating, setIsUpdating] = createSignal(false);
const increment = () => {
setIsUpdating(true);
props.push("increment", {});
};
const decrement = () => {
setIsUpdating(true);
props.push("decrement", {});
};
// Reset updating flag when state changes from server
// (In a real app, you might use a more sophisticated approach)
return (
<div class="p-6 border-2 border-blue-500 rounded-lg bg-white shadow-md">
<h2 class="text-xl font-semibold text-blue-700 mb-4">Solid.js Component</h2>
<div class="flex items-center space-x-4 mb-6">
<span class="text-4xl font-bold">{props.state.count}</span>
<div class="flex flex-col space-y-2">
<button
onClick={increment}
class="px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600 transition-colors"
>
Increment
</button>
<button
onClick={decrement}
class="px-4 py-2 bg-red-500 text-white rounded hover:bg-red-600 transition-colors"
>
Decrement
</button>
</div>
</div>
<p class="text-sm text-gray-500 italic">
This UI is rendered by Solid.js. Changes are synced back to Elixir via push_event.
</p>
</div>
);
}
@@ -0,0 +1,36 @@
import { render } from "solid-js/web";
import { createStore } from "solid-js/store";
import { SolidApp } from "../components/SolidApp";
export const SolidBridge = {
mounted() {
console.log("SolidBridge mounted");
// 1. Initialize a reactive store with initial data from the element attributes
const initialCount = parseInt(this.el.dataset.initialCount || "0");
const [state, setState] = createStore({
count: initialCount
});
// 2. Render Solid and pass the 'push' helper
// We store the cleanup function to call on destroyed()
this._cleanup = render(() => (
<SolidApp
state={state}
push={(e, p) => this.pushEvent(e, p)}
/>
), this.el);
// 3. Sync server state to Solid store
this.handleEvent("sync_state", (payload) => {
console.log("Received sync_state:", payload);
setState(payload);
});
},
destroyed() {
if (this._cleanup) {
this._cleanup();
}
}
};
@@ -0,0 +1 @@
export const hooks = {};