Dynamically render Surface components

So, reading through the source of LiveDashboard I’ve come up with something.

Essentially:

defmodule AppWeb do
  use Surface.LiveView

  data page, :string

  def render(assigns) do
    ~H"""
    <div>
      <header><h1>header</h1></header>
      <main>
        {{ @page.render(assigns) }}
      </main>
    </div>
    """
  end

  def handle_params(%{"page" => page}, _, socket} do
    {:noreply, assign(:page, resolve_page(page))}
  end

  def handle_params(_, _, socket) do
    {:noreply, assign(:page, AppWeb.Pages.Home)}
  end

  defp resolve_page("foo"), do: AppWeb.Pages.Foo
  defp resolve_page("bar"), do: AppWeb.Pages.Bar
end