Skip to content

Commit

Permalink
some live_view plays
Browse files Browse the repository at this point in the history
  • Loading branch information
phgrey committed Oct 25, 2022
1 parent 8eb3a44 commit da77615
Show file tree
Hide file tree
Showing 12 changed files with 85 additions and 51 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,4 @@ node_modules
#iDEA
*.iml
/.idea
/.vscode
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ If `./run-locally-dev.sh` is not working, try the following steps:
`asdf plugin add nodejs`
2. Run `asdf install`. This will install all the tool versions specified in the _.tool_versions_ file
Or you can install each tool version manually by typing:
`asdf install erlang` # and follow https://github.com/asdf-vm/asdf-erlang#asdf-erlang on fail (e.g. `export KERL_CONFIGURE_OPTIONS="--disable-debug --without-javac"`)
`asdf install erlang` # and follow https://github.com/asdf-vm/asdf-erlang#asdf-erlang on fail (e.g. `export KERL_CONFIGURE_OPTIONS="--without-wx --without-javac"`)
`asdf install elixir`
`asdf install nodejs`

Expand Down
2 changes: 1 addition & 1 deletion lib/moon/components/select/dropdown/icon.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ defmodule Moon.Components.Select.Dropdown.Icon do

~F"""
<div class={@class} style={@style}>
{Moon.RenderHelpers.render_component(module, props)}
{Moon.Helpers.SurfaceRender.surface_component(props |> Map.put(:module, module))}
</div>
"""
end
Expand Down
38 changes: 29 additions & 9 deletions lib/moon/helpers/surface_render.ex
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,31 @@ defmodule Moon.Helpers.SurfaceRender do

defp transform_slots(props), do: props

defp render_stateless_component(props = %{module: module}) do
@doc "used for rendering 'dead'/stateless Surface componet"
def surface_component(module, props) do
component(
&module.render/1,
module
|> get_default_props()
|> Map.merge(props |> Map.delete(:module) |> transform_slots())
module |> get_default_props() |> Map.merge(props |> transform_slots())
)
end

defp render_stateful_component(props = %{module: module}) do
def surface_component(props = %{module: module}),
do: surface_component(module, props |> Map.delete(:module))

@doc "used for rendering live/stateful Surface componet"
def surface_live_component(props = %{module: module}) do
module |> get_default_props() |> Map.merge(props |> transform_slots()) |> live_component()
end

def surface_live_component(module, props),
do: surface_live_component(Map.put(props, :module, module))

defp get_render_function(module) do
%{kind: :component} = module.__live__()
&render_stateful_component/1
&surface_live_component/1
rescue
[UndefinedFunctionError, MatchError] ->
&render_stateless_component/1
&surface_component/1
end

@doc """
Expand All @@ -49,9 +55,23 @@ defmodule Moon.Helpers.SurfaceRender do
Please note that only limited functional is supported, e.g. contexts and named
slots are out of scope, sorry.
"""
def render_surface_component(props = %{module: module}) do
def surface(props = %{module: module}) do
get_render_function(module).(props)
end

defdelegate surface(props), to: __MODULE__, as: :render_surface_component
# TODO: remove this dirty hack & make a PR to liveview if bug still exists in newer versions
# refer this bug report - https://github.com/phoenixframework/phoenix_live_view/issues/1656
# looks like phoenix_live_view v0.17.6 cant nested components with the same tag, like
# <.surface module={A}><.surface ...></.surface></.surface>
# but still can handle
# <.surface0 module={A}><.surface1 ...> ... </.surface1></.surface0>
#
# Block below works the same as:
# defdelegate surface0(props), to: __MODULE__, as: :render_surface_component
# defdelegate surface1(props), to: __MODULE__, as: :render_surface_component
# ...
# defdelegate surface99(props), to: __MODULE__, as: :render_surface_component
Enum.each(0..99, fn x ->
defdelegate unquote(:"surface#{x}")(props), to: __MODULE__, as: :surface
end)
end
35 changes: 0 additions & 35 deletions lib/moon/render_helpers.ex

This file was deleted.

8 changes: 8 additions & 0 deletions lib/moon_web.ex
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ defmodule MoonWeb do
end
end

def live_view_only do
quote do
use Phoenix.LiveView, layout: {MoonWeb.LayoutView, "live.html"}

unquote(view_helpers())
end
end

def stateless_component do
quote do
use Moon.StatelessComponent
Expand Down
2 changes: 1 addition & 1 deletion lib/moon_web/components/left_menu.ex
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ defmodule MoonWeb.Components.LeftMenu do
</:short_logo>
<:menu>
<nav class="flex flex-col grow gap-2">
<Context put={active_page: @active_page, theme_name: @theme_name, direction: @direction}>
<Context put={active_page: @active_page}>
<div class="relative z-10 fixed top-0 h-screen w-80 flex flex-col flex-grow gap-10 pt-12 pb-6 px-5 lg:px-8 overflow-y-scroll">
<div class="flex items-center flex-shrink-0 pl-3">
<a
Expand Down
4 changes: 2 additions & 2 deletions lib/moon_web/components/sidebar_link.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ defmodule MoonWeb.Components.SidebarLink do

def render(assigns) do
~F"""
<Context get={active_page: active_page, theme_name: theme_name, direction: direction}>
<Context get={active_page: active_page, global_params: globals}>
<a
data-phx-link="patch"
data-phx-link-state="push"
data-moon-active={active_page == @route}
href={live_path(MoonWeb.Endpoint, @route, theme_name: theme_name, direction: direction)}
href={live_path(MoonWeb.Endpoint, @route, globals)}
>
<Chip active={active_page == @route} variant="ghost">
<#slot />
Expand Down
2 changes: 1 addition & 1 deletion lib/moon_web/components/started/for_developer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ defmodule MoonWeb.Components.Started.ForDeveloper do
<Context get={global_params: globals}>
<a
class="text-piccolo-100 font-medium transition-colors duration-200 hover:text-hit visited:text-hit"
href={live_path(MoonWeb.Endpoint, MoonWeb.Pages.UsagePage, globals)}
href={"#{live_path(MoonWeb.Endpoint, MoonWeb.Pages.UsagePage, globals)}#HEEx-templates"}
>
can be used from SLIM and EEX templates
</a>
Expand Down
39 changes: 39 additions & 0 deletions lib/moon_web/pages/test/live_page.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
defmodule MoonWeb.Pages.Test.LivePage do
@moduledoc """
Page for visual and automatic testing of surface render helper
"""

use MoonWeb, :live_view_only

alias Moon.Components.Button
alias Moon.Components.Datepicker
alias MoonWeb.Components.Page
alias MoonWeb.Components.SidebarLink

import Moon.Helpers.SurfaceRender

def render(assigns) do
~H"""
<.surface0 module={Page} theme_name={@theme_name} active_page={@active_page} direction={@direction}>
<.surface1 module={Button} variant="secondary">Secondary</.surface1>
<.surface1 module={Datepicker}
start_date={Timex.today() |> Timex.beginning_of_week()}
end_date={Timex.today() |> Timex.end_of_week()}
week_starts_on={7}
id="datepicker"
/>
<.surface1
module={SidebarLink}
__context__={%{active_page: __MODULE__, global_params: %{
direction: @direction,
theme_name: @theme_name
}}}
route={MoonWeb.Pages.VisionPage}
>
Vision
</.surface1>
<pre><%= inspect assigns, pretty: true, structs: false %></pre>
</.surface0>
"""
end
end
2 changes: 1 addition & 1 deletion lib/moon_web/pages/usage_page.ex
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ defmodule MoonWeb.Pages.UsagePage do
</p>
<CodeSnippet>{surface_code()}</CodeSnippet>
</PageSection>
<PageSection title="LiveView only">
<PageSection title="HEEx templates">
<p>
But anyway you still can use Moon components with LiveView mechanism only. Some helpers are made for this.
But please note, that only some Surface features are supported, e.g. you can forget about contexts and named
Expand Down
1 change: 1 addition & 0 deletions lib/moon_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ defmodule MoonWeb.Router do
live "/example-pages/customers", MoonWeb.Pages.ExamplePages.CustomersPage

live "/usage", MoonWeb.Pages.UsagePage
live "/test/live", MoonWeb.Pages.Test.LivePage
end
end)
end
Expand Down

0 comments on commit da77615

Please sign in to comment.