Skip to content

Instantly share code, notes, and snippets.

@laszlokorte
Created April 22, 2026 14:33
Show Gist options
  • Select an option

  • Save laszlokorte/5fcfb6b142b180961ab2bbfee9c057c5 to your computer and use it in GitHub Desktop.

Select an option

Save laszlokorte/5fcfb6b142b180961ab2bbfee9c057c5 to your computer and use it in GitHub Desktop.
Phoenix LiveView single file
Mix.install([
{:phoenix_playground, "~> 0.1.8"}
])
defmodule DemoLive do
use Phoenix.LiveView
def mount(_params, _session, socket) do
{:ok, assign(socket, count: 0)}
end
def render(assigns) do
~H"""
<style type="text/css">
* {
all: reset;
box-sizing: border-box;
}
h1, h2, h3, h4, h5 {
margin: 0;
}
body {
margin: 0;
font-family: monospace;
}
button {
background-color: #222;
color: #fff;
border: none;
padding: 1ex;
cursor: pointer;
font: inherit;
}
button:hover {
background-color: #333;
}
button:active {
background-color: #111;
}
.row {
display: grid;
grid-auto-flow: column;
grid-auto-columns: 1fr;
align-items: center;
gap: 1ex;
}
output {
text-align: center;
}
.canvas {
display: block;
border: 1px solid gray;
margin: 1em auto;
}
</style>
<h1>Counter</h1>
<div class="row">
<button phx-click="dec">-</button>
<output>{@count}</output>
<button phx-click="inc">+</button>
</div>
<style type="text/css">
body { padding: 1em; }
</style>
<script>
window.hooks.Pen = {
mounted() {
const circle = document.createElementNS(this.el.namespaceURI, "circle")
const pt = this.el.createSVGPoint();
console.log(this.el.namespaceURI)
circle.setAttribute("cx", 0)
circle.setAttribute("cy", 0)
circle.setAttribute("r", 100)
circle.setAttribute("opacity", "0")
circle.setAttribute("fill", "purple")
this.el.appendChild(circle)
this.el.addEventListener("pointermove", e => {
const ctm = this.el.getScreenCTM();
pt.x = e.clientX
pt.y = e.clientY
const svgP = pt.matrixTransform(ctm.inverse());
circle.setAttribute("cx", svgP.x)
circle.setAttribute("cy", svgP.y)
circle.setAttribute("opacity", "1")
this.pushEvent("inc")
})
circle.addEventListener('pointerdown', (evt) => {
this.pushEvent("dec")
})
}
}
</script>
<svg phx-update="ignore" class="canvas" id="canvas" phx-hook="Pen" viewBox="-500 -500 1000 1000" width="500" height="500"></svg>
"""
end
def handle_event("inc", _params, socket) do
{:noreply, assign(socket, count: socket.assigns.count + 1)}
end
def handle_event("dec", _params, socket) do
{:noreply, assign(socket, count: socket.assigns.count - 1)}
end
end
PhoenixPlayground.start(live: DemoLive)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment