Skip to content

Commit

Permalink
Simplified live generator (#5900)
Browse files Browse the repository at this point in the history
* Convert FormComponent to live view

* Support redirects to index and show

* Remove modal component

* Colocate live templates
  • Loading branch information
mcrumm authored Aug 15, 2024
1 parent 412a07d commit 83f3339
Show file tree
Hide file tree
Showing 17 changed files with 257 additions and 499 deletions.
99 changes: 2 additions & 97 deletions installer/templates/phx_web/components/core_components.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ defmodule <%= @web_namespace %>.CoreComponents do
Provides core UI components.
At first glance, this module may seem daunting, but its goal is to provide
core building blocks for your application, such as modals, tables, and
forms. The components consist mostly of markup and are well-documented
core building blocks for your application, such as tables, forms, and
inputs. The components consist mostly of markup and are well-documented
with doc strings and declarative assigns. You may customize and style
them in any way you want, based on your application growth and needs.
Expand All @@ -19,76 +19,6 @@ defmodule <%= @web_namespace %>.CoreComponents do
alias Phoenix.LiveView.JS<%= if @gettext do %>
import <%= @web_namespace %>.Gettext<% end %>

@doc """
Renders a modal.
## Examples
<.modal id="confirm-modal">
This is a modal.
</.modal>
JS commands may be passed to the `:on_cancel` to configure
the closing/cancel event, for example:
<.modal id="confirm" on_cancel={JS.navigate(~p"/posts")}>
This is another modal.
</.modal>
"""
attr :id, :string, required: true
attr :show, :boolean, default: false
attr :on_cancel, JS, default: %JS{}
slot :inner_block, required: true

def modal(assigns) do
~H"""
<div
id={@id}
phx-mounted={@show && show_modal(@id)}
phx-remove={hide_modal(@id)}
data-cancel={JS.exec(@on_cancel, "phx-remove")}
class="relative z-50 hidden"
>
<div id={"#{@id}-bg"} class="bg-zinc-50/90 fixed inset-0 transition-opacity" aria-hidden="true" />
<div
class="fixed inset-0 overflow-y-auto"
aria-labelledby={"#{@id}-title"}
aria-describedby={"#{@id}-description"}
role="dialog"
aria-modal="true"
tabindex="0"
>
<div class="flex min-h-full items-center justify-center">
<div class="w-full max-w-3xl p-4 sm:p-6 lg:py-8">
<.focus_wrap
id={"#{@id}-container"}
phx-window-keydown={JS.exec("data-cancel", to: "##{@id}")}
phx-key="escape"
phx-click-away={JS.exec("data-cancel", to: "##{@id}")}
class="shadow-zinc-700/10 ring-zinc-700/10 relative hidden rounded-2xl bg-white p-14 shadow-lg ring-1 transition"
>
<div class="absolute top-6 right-5">
<button
phx-click={JS.exec("data-cancel", to: "##{@id}")}
type="button"
class="-m-3 flex-none p-3 opacity-20 hover:opacity-40"
aria-label=<%= maybe_heex_attr_gettext.("close", @gettext) %>
>
<.icon name="hero-x-mark-solid" class="h-5 w-5" />
</button>
</div>
<div id={"#{@id}-content"}>
<%%= render_slot(@inner_block) %>
</div>
</.focus_wrap>
</div>
</div>
</div>
</div>
"""
end

@doc """
Renders flash notices.
Expand Down Expand Up @@ -620,31 +550,6 @@ defmodule <%= @web_namespace %>.CoreComponents do
)
end

def show_modal(js \\ %JS{}, id) when is_binary(id) do
js
|> JS.show(to: "##{id}")
|> JS.show(
to: "##{id}-bg",
time: 300,
transition: {"transition-all ease-out duration-300", "opacity-0", "opacity-100"}
)
|> show("##{id}-container")
|> JS.add_class("overflow-hidden", to: "body")
|> JS.focus_first(to: "##{id}-content")
end

def hide_modal(js \\ %JS{}, id) do
js
|> JS.hide(
to: "##{id}-bg",
transition: {"transition-all ease-in duration-200", "opacity-100", "opacity-0"}
)
|> hide("##{id}-container")
|> JS.hide(to: "##{id}", transition: {"block", "block", "hidden"})
|> JS.remove_class("overflow-hidden", to: "body")
|> JS.pop_focus()
end

@doc """
Translates an error message using gettext.
"""<%= if @gettext do %>
Expand Down
12 changes: 4 additions & 8 deletions integration_test/test/code_generation/app_with_defaults_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,9 @@ defmodule Phoenix.Integration.CodeGeneration.AppWithDefaultsTest do
pipe_through [:browser]
live "/posts", PostLive.Index, :index
live "/posts/new", PostLive.Index, :new
live "/posts/:id/edit", PostLive.Index, :edit
live "/posts/new", PostLive.Form, :new
live "/posts/:id", PostLive.Show, :show
live "/posts/:id/show/edit", PostLive.Show, :edit
live "/posts/:id/edit", PostLive.Form, :edit
end
""")
end)
Expand All @@ -158,11 +156,9 @@ defmodule Phoenix.Integration.CodeGeneration.AppWithDefaultsTest do
pipe_through [:browser]
live "/posts", PostLive.Index, :index
live "/posts/new", PostLive.Index, :new
live "/posts/:id/edit", PostLive.Index, :edit
live "/posts/new", PostLive.Form, :new
live "/posts/:id", PostLive.Show, :show
live "/posts/:id/show/edit", PostLive.Show, :edit
live "/posts/:id/edit", PostLive.Form, :edit
end
""")
end)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,9 @@ defmodule Phoenix.Integration.CodeGeneration.AppWithMSSQLAdapterTest do
pipe_through [:browser]
live "/posts", PostLive.Index, :index
live "/posts/new", PostLive.Index, :new
live "/posts/:id/edit", PostLive.Index, :edit
live "/posts/new", PostLive.Form, :new
live "/posts/:id", PostLive.Show, :show
live "/posts/:id/show/edit", PostLive.Show, :edit
live "/posts/:id/edit", PostLive.Form, :edit
end
""")
end)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,9 @@ defmodule Phoenix.Integration.CodeGeneration.AppWithMySqlAdapterTest do
pipe_through [:browser]
live "/posts", PostLive.Index, :index
live "/posts/new", PostLive.Index, :new
live "/posts/:id/edit", PostLive.Index, :edit
live "/posts/new", PostLive.Form, :new
live "/posts/:id", PostLive.Show, :show
live "/posts/:id/show/edit", PostLive.Show, :edit
live "/posts/:id/edit", PostLive.Form, :edit
end
""")
end)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,9 @@ defmodule Phoenix.Integration.CodeGeneration.AppWithSQLite3AdapterTest do
pipe_through [:browser]
live "/posts", PostLive.Index, :index
live "/posts/new", PostLive.Index, :new
live "/posts/:id/edit", PostLive.Index, :edit
live "/posts/new", PostLive.Form, :new
live "/posts/:id", PostLive.Show, :show
live "/posts/:id/show/edit", PostLive.Show, :edit
live "/posts/:id/edit", PostLive.Form, :edit
end
""")
end)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,9 @@ defmodule Phoenix.Integration.CodeGeneration.UmbrellaAppWithDefaultsTest do
pipe_through [:browser]
live "/posts", PostLive.Index, :index
live "/posts/new", PostLive.Index, :new
live "/posts/:id/edit", PostLive.Index, :edit
live "/posts/new", PostLive.Form, :new
live "/posts/:id", PostLive.Show, :show
live "/posts/:id/show/edit", PostLive.Show, :edit
live "/posts/:id/edit", PostLive.Form, :edit
end
""")
end)
Expand All @@ -165,11 +163,9 @@ defmodule Phoenix.Integration.CodeGeneration.UmbrellaAppWithDefaultsTest do
pipe_through [:browser]
live "/posts", PostLive.Index, :index
live "/posts/new", PostLive.Index, :new
live "/posts/:id/edit", PostLive.Index, :edit
live "/posts/new", PostLive.Form, :new
live "/posts/:id", PostLive.Show, :show
live "/posts/:id/show/edit", PostLive.Show, :edit
live "/posts/:id/edit", PostLive.Form, :edit
end
""")
end)
Expand Down
2 changes: 1 addition & 1 deletion lib/mix/phoenix/schema.ex
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ defmodule Mix.Phoenix.Schema do
@doc """
Converts the given value to map format when it is a date, time, datetime or naive_datetime.
Since `form_component.html.heex` generated by the live generator uses selects for dates and/or
Since `form.html.heex` generated by the live generator uses selects for dates and/or
times, fixtures must use map format for those fields in order to submit the live form.
"""
def live_form_value(%Date{} = date), do: Calendar.strftime(date, "%Y-%m-%d")
Expand Down
25 changes: 10 additions & 15 deletions lib/mix/tasks/phx.gen.live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ defmodule Mix.Tasks.Phx.Gen.Live do
types. See `mix help phx.gen.schema` for more information on attributes.
When this command is run for the first time, a `Components` module will be
created if it does not exist, along with the resource level LiveViews and
components, including `UserLive.Index`, `UserLive.Show`, and
`UserLive.FormComponent` modules for the new resource.
created if it does not exist, along with the resource level LiveViews,
including `UserLive.Index`, `UserLive.Show`, and `UserLive.Form` modules for
the new resource.
> Note: A resource may also be split
> over distinct contexts (such as `Accounts.User` and `Payments.User`).
Expand All @@ -32,20 +32,18 @@ defmodule Mix.Tasks.Phx.Gen.Live do
* a schema in `lib/app/accounts/user.ex`, with a `users` table
* a LiveView in `lib/app_web/live/user_live/show.ex`
* a LiveView in `lib/app_web/live/user_live/index.ex`
* a LiveComponent in `lib/app_web/live/user_live/form_component.ex`
* a helpers module in `lib/app_web/live/live_helpers.ex` with a modal
* a LiveView in `lib/app_web/live/user_live/form.ex`
* a components module in `lib/app_web/components/core_components.ex`
After file generation is complete, there will be output regarding required
updates to the `lib/app_web/router.ex` file.
Add the live routes to your browser scope in lib/app_web/router.ex:
live "/users", UserLive.Index, :index
live "/users/new", UserLive.Index, :new
live "/users/:id/edit", UserLive.Index, :edit
live "/users/new", UserLive.Form, :new
live "/users/:id", UserLive.Show, :show
live "/users/:id/show/edit", UserLive.Show, :edit
live "/users/:id/edit", UserLive.Form, :edit
## The context app
Expand Down Expand Up @@ -147,9 +145,7 @@ defmodule Mix.Tasks.Phx.Gen.Live do
[
{:eex, "show.ex", Path.join(web_live, "show.ex")},
{:eex, "index.ex", Path.join(web_live, "index.ex")},
{:eex, "form_component.ex", Path.join(web_live, "form_component.ex")},
{:eex, "index.html.heex", Path.join(web_live, "index.html.heex")},
{:eex, "show.html.heex", Path.join(web_live, "show.html.heex")},
{:eex, "form.ex", Path.join(web_live, "form.ex")},
{:eex, "live_test.exs", Path.join(test_live, "#{schema.singular}_live_test.exs")},
{:new_eex, "core_components.ex",
Path.join([web_prefix, "components", "core_components.ex"])}
Expand Down Expand Up @@ -262,10 +258,9 @@ defmodule Mix.Tasks.Phx.Gen.Live do
defp live_route_instructions(schema) do
[
~s|live "/#{schema.plural}", #{inspect(schema.alias)}Live.Index, :index\n|,
~s|live "/#{schema.plural}/new", #{inspect(schema.alias)}Live.Index, :new\n|,
~s|live "/#{schema.plural}/:id/edit", #{inspect(schema.alias)}Live.Index, :edit\n\n|,
~s|live "/#{schema.plural}/new", #{inspect(schema.alias)}Live.Form, :new\n|,
~s|live "/#{schema.plural}/:id", #{inspect(schema.alias)}Live.Show, :show\n|,
~s|live "/#{schema.plural}/:id/show/edit", #{inspect(schema.alias)}Live.Show, :edit|
~s|live "/#{schema.plural}/:id/edit", #{inspect(schema.alias)}Live.Form, :edit|
]
end

Expand Down
Loading

0 comments on commit 83f3339

Please sign in to comment.