diff --git a/lib/phoenix_component/declarative.ex b/lib/phoenix_component/declarative.ex index e61f33720c..5b309aa354 100644 --- a/lib/phoenix_component/declarative.ex +++ b/lib/phoenix_component/declarative.ex @@ -817,7 +817,7 @@ defmodule Phoenix.Component.Declarative do defp build_attrs_docs(attrs) do [ "## Attributes\n", - for attr <- attrs, attr.doc != false, attr.type != :global, into: [] do + for attr <- attrs, attr.doc != false and attr.type != :global do [ "\n* ", build_attr_name(attr), @@ -828,10 +828,10 @@ defmodule Phoenix.Component.Declarative do build_attr_values_or_examples(attr) ] end, - if Enum.any?(attrs, &(&1.type == :global)) do - "\n* Global attributes are accepted." - else - "" + # global always goes at the end + case Enum.find(attrs, &(&1.type === :global)) do + nil -> [] + attr -> build_attr_doc_and_default(attr, " ") end ] end @@ -904,17 +904,17 @@ defmodule Phoenix.Component.Declarative do end defp build_attr_doc_and_default(%{doc: doc, type: :global, opts: opts}, indent) do - case Keyword.fetch(opts, :include) do - {:ok, [_ | _] = inc} -> - if doc do - [build_doc(doc, indent, true), "Supports all globals plus: ", build_literal(inc), "."] - else - ["Supports all globals plus: ", build_literal(inc), "."] - end - - _ -> - if doc, do: [build_doc(doc, indent, false)], else: [] - end + [ + "\n* Global attributes are accepted.", + if(doc, do: [" ", build_doc(doc, indent, false)], else: []), + case Keyword.get(opts, :include) do + inc when is_list(inc) and inc != [] -> + [" ", "Supports all globals plus:", " ", build_literal(inc), "."] + + _ -> + [] + end + ] end defp build_attr_doc_and_default(%{doc: doc, opts: opts}, indent) do diff --git a/test/phoenix_component/declarative_assigns_test.exs b/test/phoenix_component/declarative_assigns_test.exs index adf503edc9..7662941be9 100644 --- a/test/phoenix_component/declarative_assigns_test.exs +++ b/test/phoenix_component/declarative_assigns_test.exs @@ -867,6 +867,27 @@ defmodule Phoenix.ComponentDeclarativeAssignsTest do * Global attributes are accepted. """, + fun_attr_global_doc_include: """ + ## Attributes + + * Global attributes are accepted. These are passed to the inner input field. Supports all globals plus: `["value"]`. + """, + fun_attr_global_doc: """ + ## Attributes + + * Global attributes are accepted. These are passed to the inner input field. + """, + fun_attr_global_include: """ + ## Attributes + + * Global attributes are accepted. Supports all globals plus: `["value"]`. + """, + fun_attr_global_and_regular: """ + ## Attributes + + * `name` (`:string`) - The form input name. + * Global attributes are accepted. These are passed to the inner input field. + """, fun_attr_struct: """ ## Attributes @@ -1020,7 +1041,7 @@ defmodule Phoenix.ComponentDeclarativeAssignsTest do assert Enum.find_value(abstract_code, fn {:function, line, :fun_doc_false, 1, _} -> line _ -> nil - end) == 105 + end) == 118 end test "does not override signature of Elixir functions" do diff --git a/test/support/live_views/components.ex b/test/support/live_views/components.ex index c6b6bb89b9..23d085e5eb 100644 --- a/test/support/live_views/components.ex +++ b/test/support/live_views/components.ex @@ -51,6 +51,19 @@ defmodule Phoenix.LiveViewTest.FunctionComponentWithAttrs do attr :attr, :global def fun_attr_global(assigns), do: ~H[] + attr :rest, :global, doc: "These are passed to the inner input field" + def fun_attr_global_doc(assigns), do: ~H[] + + attr :rest, :global, doc: "These are passed to the inner input field", include: ~w(value) + def fun_attr_global_doc_include(assigns), do: ~H[] + + attr :rest, :global, include: ~w(value) + def fun_attr_global_include(assigns), do: ~H[] + + attr :name, :string, doc: "The form input name" + attr :rest, :global, doc: "These are passed to the inner input field" + def fun_attr_global_and_regular(assigns), do: ~H[] + attr :attr, Struct def fun_attr_struct(assigns), do: ~H[]