mirror of
https://github.com/woutdp/live_svelte
synced 2026-05-24 09:28:21 +00:00
Extra example in example_project
This commit is contained in:
parent
fe731a4738
commit
0b04c5d935
9 changed files with 153 additions and 95 deletions
10
example_project/assets/svelte/SimpleCounter.svelte
Normal file
10
example_project/assets/svelte/SimpleCounter.svelte
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<script>
|
||||
export let number
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col justify-center items-center gap-4 p-4">
|
||||
<div class="flex flex-row items-center justify-center gap-10">
|
||||
<span class="text-xl">{number}</span>
|
||||
<button class="plus" phx-click="increment">+1</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -15,47 +15,53 @@
|
|||
</div>
|
||||
<div class="flex">
|
||||
<a
|
||||
href="/svelte-1"
|
||||
href={~p"/simple"}
|
||||
class="font-semibold leading-6 text-zinc-900 hover:text-zinc-700 hover:underline p-2"
|
||||
>
|
||||
1
|
||||
</a>
|
||||
<a
|
||||
href="/svelte-2"
|
||||
href={~p"/counter"}
|
||||
class="font-semibold leading-6 text-zinc-900 hover:text-zinc-700 hover:underline p-2"
|
||||
>
|
||||
2
|
||||
</a>
|
||||
<a
|
||||
href="/live-example-1"
|
||||
href={~p"/plus-minus-svelte"}
|
||||
class="font-semibold leading-6 text-zinc-900 hover:text-zinc-700 hover:underline p-2"
|
||||
>
|
||||
3
|
||||
</a>
|
||||
<a
|
||||
href="/live-example-2"
|
||||
href={~p"/plus-minus-liveview"}
|
||||
class="font-semibold leading-6 text-zinc-900 hover:text-zinc-700 hover:underline p-2"
|
||||
>
|
||||
4
|
||||
</a>
|
||||
<a
|
||||
href="/live-example-3"
|
||||
href={~p"/plus-minus-hybrid"}
|
||||
class="font-semibold leading-6 text-zinc-900 hover:text-zinc-700 hover:underline p-2"
|
||||
>
|
||||
5
|
||||
</a>
|
||||
<a
|
||||
href="/live-example-4"
|
||||
href={~p"/log-list"}
|
||||
class="font-semibold leading-6 text-zinc-900 hover:text-zinc-700 hover:underline p-2"
|
||||
>
|
||||
6
|
||||
</a>
|
||||
<a
|
||||
href="/live-example-5"
|
||||
href={~p"/breaking-news"}
|
||||
class="font-semibold leading-6 text-zinc-900 hover:text-zinc-700 hover:underline p-2"
|
||||
>
|
||||
7
|
||||
</a>
|
||||
<a
|
||||
href={~p"/chat"}
|
||||
class="font-semibold leading-6 text-zinc-900 hover:text-zinc-700 hover:underline p-2"
|
||||
>
|
||||
8
|
||||
</a>
|
||||
</div>
|
||||
<div class="flex items-center gap-4">
|
||||
<a
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ defmodule ExampleWeb.LiveExample1 do
|
|||
<span class="text-xl"><%= @number %></span>
|
||||
<button class="plus" phx-click="add">+<%= @amount %></button>
|
||||
</div>
|
||||
|
||||
<label>
|
||||
Amount:
|
||||
<input
|
||||
|
|
|
|||
|
|
@ -3,17 +3,29 @@ defmodule ExampleWeb.LiveExample2 do
|
|||
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<h1 class="flex justify-center mb-10 font-bold">Hybrid: LiveView + Svelte</h1>
|
||||
|
||||
<LiveSvelte.render name="CounterHybrid" props={%{number: @number}} />
|
||||
<div>
|
||||
<div class="bg-[#eee] rounded p-2 m-2 w-[fit-content]">
|
||||
<h1 class="text-xs font-bold flex items-end justify-end">LiveView</h1>
|
||||
<div class="flex flex-col justify-center items-center gap-4 p-4">
|
||||
<div class="flex flex-row items-center justify-center gap-10">
|
||||
<span class="text-xl"><%= @number %></span>
|
||||
<button class="plus" phx-click="increment">+1</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-[#eee] rounded p-2 m-2 w-[fit-content]">
|
||||
<h1 class="text-xs font-bold flex items-end justify-end">LiveSvelte</h1>
|
||||
<LiveSvelte.render name="SimpleCounter" props={%{number: @number}} />
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
def mount(_session, _params, socket) do
|
||||
{:ok, assign(socket, %{number: 10})}
|
||||
{:ok, assign(socket, :number, 10)}
|
||||
end
|
||||
|
||||
def handle_event("set_number", %{"value" => number}, socket) do
|
||||
{:noreply, assign(socket, :number, String.to_integer(number))}
|
||||
def handle_event("increment", _values, socket) do
|
||||
{:noreply, assign(socket, :number, socket.assigns.number + 1)}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,28 +3,17 @@ defmodule ExampleWeb.LiveExample3 do
|
|||
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<LiveSvelte.render name="LogList" props={%{items: @items}} />
|
||||
<h1 class="flex justify-center mb-10 font-bold">Hybrid: LiveView + Svelte</h1>
|
||||
|
||||
<LiveSvelte.render name="CounterHybrid" props={%{number: @number}} />
|
||||
"""
|
||||
end
|
||||
|
||||
def mount(_params, _session, socket) do
|
||||
if connected?(socket), do: :timer.send_interval(1000, self(), :tick)
|
||||
{:ok, assign(socket, :items, [])}
|
||||
def mount(_session, _params, socket) do
|
||||
{:ok, assign(socket, %{number: 10})}
|
||||
end
|
||||
|
||||
def handle_event("add_item", %{"name" => name}, socket) do
|
||||
{:noreply, assign(socket, :items, add_log(socket, name))}
|
||||
end
|
||||
|
||||
def handle_info(:tick, socket) do
|
||||
datetime =
|
||||
DateTime.utc_now()
|
||||
|> DateTime.to_string()
|
||||
|
||||
{:noreply, assign(socket, :items, add_log(socket, datetime))}
|
||||
end
|
||||
|
||||
defp add_log(socket, body) do
|
||||
[%{id: System.unique_integer([:positive]), name: body} | socket.assigns.items]
|
||||
def handle_event("set_number", %{"value" => number}, socket) do
|
||||
{:noreply, assign(socket, :number, String.to_integer(number))}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,39 +1,30 @@
|
|||
defmodule ExampleWeb.LiveExample4 do
|
||||
use ExampleWeb, :live_view
|
||||
|
||||
@initial_news [
|
||||
%{id: 1, body: "Giant Pink Elephant Sighted Downtown"},
|
||||
%{id: 2, body: "Local Cat Becomes Mayor of Small Town"},
|
||||
%{id: 3, body: "Scientists Discover New Flavor of Ice Cream"},
|
||||
%{
|
||||
id: 4,
|
||||
body: "World's Largest Pizza Baked in Local Pizzeria, Still Not Big Enough for Customers"
|
||||
},
|
||||
%{
|
||||
id: 5,
|
||||
body:
|
||||
"Clown Epidemic Sweeps Through Town, Everyone Laughs Until They Realize the Clowns Aren't Joking"
|
||||
}
|
||||
]
|
||||
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<LiveSvelte.render name="BreakingNews" props={%{news: @news}} />
|
||||
<LiveSvelte.render name="LogList" props={%{items: @items}} />
|
||||
"""
|
||||
end
|
||||
|
||||
def mount(_params, _session, socket) do
|
||||
{:ok, assign(socket, :news, @initial_news)}
|
||||
if connected?(socket), do: :timer.send_interval(1000, self(), :tick)
|
||||
{:ok, assign(socket, :items, [])}
|
||||
end
|
||||
|
||||
def handle_event("remove_news_item", %{"id" => id}, socket) do
|
||||
updated_news = Enum.reject(socket.assigns.news, fn item -> item.id == id end)
|
||||
{:noreply, assign(socket, :news, updated_news)}
|
||||
def handle_event("add_item", %{"name" => name}, socket) do
|
||||
{:noreply, assign(socket, :items, add_log(socket, name))}
|
||||
end
|
||||
|
||||
def handle_event("add_news_item", %{"body" => body}, socket) do
|
||||
new_item = %{id: System.unique_integer([:positive]), body: body}
|
||||
updated_news = socket.assigns.news ++ [new_item]
|
||||
{:noreply, assign(socket, :news, updated_news)}
|
||||
def handle_info(:tick, socket) do
|
||||
datetime =
|
||||
DateTime.utc_now()
|
||||
|> DateTime.to_string()
|
||||
|
||||
{:noreply, assign(socket, :items, add_log(socket, datetime))}
|
||||
end
|
||||
|
||||
defp add_log(socket, body) do
|
||||
[%{id: System.unique_integer([:positive]), name: body} | socket.assigns.items]
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,49 +1,39 @@
|
|||
defmodule ExampleWeb.LiveExample5 do
|
||||
use ExampleWeb, :live_view
|
||||
|
||||
@topic "public"
|
||||
@event_new_message "new_message"
|
||||
@initial_news [
|
||||
%{id: 1, body: "Giant Pink Elephant Sighted Downtown"},
|
||||
%{id: 2, body: "Local Cat Becomes Mayor of Small Town"},
|
||||
%{id: 3, body: "Scientists Discover New Flavor of Ice Cream"},
|
||||
%{
|
||||
id: 4,
|
||||
body: "World's Largest Pizza Baked in Local Pizzeria, Still Not Big Enough for Customers"
|
||||
},
|
||||
%{
|
||||
id: 5,
|
||||
body:
|
||||
"Clown Epidemic Sweeps Through Town, Everyone Laughs Until They Realize the Clowns Aren't Joking"
|
||||
}
|
||||
]
|
||||
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<div class="flex justify-center items-center h-full w-full">
|
||||
<%= unless @name do %>
|
||||
<form phx-submit="set_name">
|
||||
<!-- svelte-ignore a11y-autofocus -->
|
||||
<input type="text" placeholder="Name" name="name" class="rounded" autofocus autocomplete="name" />
|
||||
<button class="py-2 px-4 bg-black text-white rounded">Join</button>
|
||||
</form>
|
||||
<% else %>
|
||||
<LiveSvelte.render
|
||||
name="Chat"
|
||||
props={%{messages: @messages, name: @name}}
|
||||
class="w-full h-full flex justify-center items-center"
|
||||
/>
|
||||
<% end %>
|
||||
</div>
|
||||
<LiveSvelte.render name="BreakingNews" props={%{news: @news}} />
|
||||
"""
|
||||
end
|
||||
|
||||
def mount(_params, _session, socket) do
|
||||
ExampleWeb.Endpoint.subscribe(@topic)
|
||||
{:ok, assign(socket, messages: [], name: nil)}
|
||||
{:ok, assign(socket, :news, @initial_news)}
|
||||
end
|
||||
|
||||
def handle_event("set_name", %{"name" => ""}, socket), do: {:noreply, socket}
|
||||
def handle_event("set_name", %{"name" => name}, socket), do: {:noreply, assign(socket, name: name)}
|
||||
|
||||
def handle_event("send_message", payload, socket) do
|
||||
payload =
|
||||
payload
|
||||
|> Map.put(:name, socket.assigns.name)
|
||||
|> Map.put(:id, System.unique_integer([:positive]))
|
||||
|
||||
ExampleWeb.Endpoint.broadcast(@topic, @event_new_message, payload)
|
||||
|
||||
{:noreply, socket}
|
||||
def handle_event("remove_news_item", %{"id" => id}, socket) do
|
||||
updated_news = Enum.reject(socket.assigns.news, fn item -> item.id == id end)
|
||||
{:noreply, assign(socket, :news, updated_news)}
|
||||
end
|
||||
|
||||
def handle_info(%{topic: @topic, event: @event_new_message, payload: payload}, socket) do
|
||||
{:noreply, assign(socket, messages: socket.assigns.messages ++ [payload])}
|
||||
def handle_event("add_news_item", %{"body" => body}, socket) do
|
||||
new_item = %{id: System.unique_integer([:positive]), body: body}
|
||||
updated_news = socket.assigns.news ++ [new_item]
|
||||
{:noreply, assign(socket, :news, updated_news)}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
58
example_project/lib/example_web/live/live_example_6.ex
Normal file
58
example_project/lib/example_web/live/live_example_6.ex
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
defmodule ExampleWeb.LiveExample6 do
|
||||
use ExampleWeb, :live_view
|
||||
|
||||
@topic "public"
|
||||
@event_new_message "new_message"
|
||||
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<div class="flex justify-center items-center h-full w-full">
|
||||
<%= unless @name do %>
|
||||
<form phx-submit="set_name">
|
||||
<!-- svelte-ignore a11y-autofocus -->
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Name"
|
||||
name="name"
|
||||
class="rounded"
|
||||
autofocus
|
||||
autocomplete="name"
|
||||
/>
|
||||
<button class="py-2 px-4 bg-black text-white rounded">Join</button>
|
||||
</form>
|
||||
<% else %>
|
||||
<LiveSvelte.render
|
||||
name="Chat"
|
||||
props={%{messages: @messages, name: @name}}
|
||||
class="w-full h-full flex justify-center items-center"
|
||||
/>
|
||||
<% end %>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
def mount(_params, _session, socket) do
|
||||
ExampleWeb.Endpoint.subscribe(@topic)
|
||||
{:ok, assign(socket, messages: [], name: nil)}
|
||||
end
|
||||
|
||||
def handle_event("set_name", %{"name" => ""}, socket), do: {:noreply, socket}
|
||||
|
||||
def handle_event("set_name", %{"name" => name}, socket),
|
||||
do: {:noreply, assign(socket, name: name)}
|
||||
|
||||
def handle_event("send_message", payload, socket) do
|
||||
payload =
|
||||
payload
|
||||
|> Map.put(:name, socket.assigns.name)
|
||||
|> Map.put(:id, System.unique_integer([:positive]))
|
||||
|
||||
ExampleWeb.Endpoint.broadcast(@topic, @event_new_message, payload)
|
||||
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
def handle_info(%{topic: @topic, event: @event_new_message, payload: payload}, socket) do
|
||||
{:noreply, assign(socket, messages: socket.assigns.messages ++ [payload])}
|
||||
end
|
||||
end
|
||||
|
|
@ -18,13 +18,14 @@ defmodule ExampleWeb.Router do
|
|||
pipe_through :browser
|
||||
|
||||
get "/", PageController, :home
|
||||
get "/svelte-1", PageController, :svelte_1
|
||||
get "/svelte-2", PageController, :svelte_2
|
||||
live "/live-example-1", LiveExample1
|
||||
live "/live-example-2", LiveExample2
|
||||
live "/live-example-3", LiveExample3
|
||||
live "/live-example-4", LiveExample4
|
||||
live "/live-example-5", LiveExample5
|
||||
get "/simple", PageController, :svelte_1
|
||||
get "/plus-minus-svelte", PageController, :svelte_2
|
||||
live "/plus-minus-liveview", LiveExample1
|
||||
live "/counter", LiveExample2
|
||||
live "/plus-minus-hybrid", LiveExample3
|
||||
live "/log-list", LiveExample4
|
||||
live "/breaking-news", LiveExample5
|
||||
live "/chat", LiveExample6
|
||||
end
|
||||
|
||||
# Other scopes may use custom stacks.
|
||||
|
|
|
|||
Loading…
Reference in a new issue