Add socket prop to skip ssr for live mounts and navigation

This commit is contained in:
Dmitrii Maganov 2023-08-18 09:48:07 +03:00 committed by Wout De Puysseleir
parent d4bd5f5a9b
commit 6cb9ce7c77
10 changed files with 28 additions and 21 deletions

View file

@ -25,6 +25,7 @@ defmodule ExampleWeb.LiveExample6 do
messages={@messages}
name={@name}
class="w-full h-full flex justify-center items-center"
socket={@socket}
/>
</div>
"""

View file

@ -6,7 +6,7 @@ defmodule ExampleWeb.LiveExample3 do
~H"""
<h1 class="flex justify-center mb-10 font-bold">Hybrid: LiveView + Svelte</h1>
<.CounterHybrid number={@number} />
<.CounterHybrid number={@number} socket={@socket} />
"""
end

View file

@ -5,7 +5,7 @@ defmodule ExampleWeb.LiveJson do
~H"""
<div class="flex gap-10">
<div>
SSR: <.svelte name="LiveJson" live_json_props={%{big_data_set: @ljbig_data_set}} />
SSR: <.svelte name="LiveJson" live_json_props={%{big_data_set: @ljbig_data_set}} socket={@socket} />
</div>
<div>
No SSR:

View file

@ -11,8 +11,8 @@ defmodule ExampleWeb.LiveLights do
~H"""
<div class="max-w-screen-xl mx-auto p-4 flex flex-col gap-4">
<h1 class="text-center text-2xl font-light my-4">Light Bulb Controller</h1>
<.svelte name="LightStatusBar" props={%{brightness: @brightness}} />
<.svelte name="LightControllers" props={%{isOn: isOn?(@brightness)}} />
<.svelte name="LightStatusBar" props={%{brightness: @brightness}} socket={@socket} />
<.svelte name="LightControllers" props={%{isOn: isOn?(@brightness)}} socket={@socket} />
</div>
"""
end

View file

@ -3,7 +3,7 @@ defmodule ExampleWeb.LiveExample4 do
def render(assigns) do
~H"""
<.svelte name="LogList" props={%{items: @items}} />
<.svelte name="LogList" props={%{items: @items}} socket={@socket} />
"""
end

View file

@ -15,7 +15,7 @@ defmodule ExampleWeb.LiveExample2 do
</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>
<.svelte name="SimpleCounter" props={%{number: @number}} />
<.svelte name="SimpleCounter" props={%{number: @number}} socket={@socket} />
</div>
</div>
"""

View file

@ -3,7 +3,7 @@ defmodule ExampleWeb.LiveSlotsExperiment do
def render(assigns) do
~H"""
<.svelte name="SlotsExperiment">
<.svelte name="SlotsExperiment" socket={@socket}>
Inside Slot
</.svelte>
"""

View file

@ -11,7 +11,7 @@ defmodule ExampleWeb.LiveStruct do
def render(assigns) do
~H"""
<h1 class="text-lg">An example of how to pass a struct to Svelte:</h1>
<.svelte name="Struct" props={%{struct: @struct}} />
<.svelte name="Struct" props={%{struct: @struct}} socket={@socket} />
"""
end

View file

@ -3,6 +3,7 @@ defmodule LiveSvelte do
import Phoenix.HTML
import LiveSvelte.LiveJson
alias Phoenix.LiveView
alias LiveSvelte.Slots
alias LiveSvelte.SSR
@ -38,6 +39,13 @@ defmodule LiveSvelte do
examples: [true, false]
)
attr(
:socket,
:map,
default: nil,
doc: "LiveView socket, should be provided when rendering inside LiveView"
)
attr(
:live_json_props,
:map,
@ -55,6 +63,7 @@ defmodule LiveSvelte do
"""
def svelte(assigns) do
init = assigns.__changed__ == nil
dead = assigns.socket == nil or not LiveView.connected?(assigns.socket)
slots =
assigns
@ -62,7 +71,7 @@ defmodule LiveSvelte do
|> Slots.js_process()
ssr_code =
if init and assigns.ssr do
if init and dead and assigns.ssr do
try do
props =
Map.merge(
@ -138,10 +147,10 @@ defmodule LiveSvelte do
end
@doc false
def get_ssr(assigns) do
case get_in(assigns, [:svelte_opts, :ssr]) do
nil -> true
ssr -> ssr
def get_socket(assigns) do
case get_in(assigns, [:svelte_opts, :socket]) || assigns[:socket] do
%LiveView.Socket{} = socket -> socket
_ -> nil
end
end
@ -158,7 +167,8 @@ defmodule LiveSvelte do
<LiveSvelte.svelte
name={"_build/#{__MODULE__}"}
props={get_props(assigns)}
ssr={get_ssr(assigns)}
socket={get_socket(assigns)}
ssr={get_in(assigns, [:svelte_opts, :ssr]) != false}
class={get_in(assigns, [:svelte_opts, :class])}
/>
"""

View file

@ -23,25 +23,21 @@ defmodule LiveSvelte.Components do
defp name_to_function(name) do
quote do
def unquote(:"#{name}")(assigns) do
props =
assigns
|> Map.filter(fn
{:svelte_opts, _v} -> false
{k, _v} -> k not in [:__changed__, :__given__, :ssr]
_ -> false
end)
props = Map.drop(assigns, [:__changed__, :__given__, :ssr, :class, :socket])
var!(assigns) =
assigns
|> Map.put(:__component_name, unquote(name))
|> Map.put_new(:ssr, true)
|> Map.put_new(:class, nil)
|> Map.put_new(:socket, nil)
|> assign(:props, props)
~H"""
<LiveSvelte.svelte
name={@__component_name}
class={@class}
socket={@socket}
ssr={@ssr}
props={@props}
/>