Here's a simple function to check if the slot is empty, where empty can mean.
- No slot provided
- Slot provided but has only whitespace
defp slot_empty?(slot) do case slot do [] -> true slots when is_list(slots) -> not Enum.any?(slots, fn slot -> case slot do %{inner_block: inner_block} when is_function(inner_block) -> try do {:ok, inner_block.(%{}, nil) |> Phoenix.HTML.html_escape()} rescue _ -> :error end |> case do {:ok, html} -> html |> Phoenix.HTML.safe_to_string() |> String.trim() |> Kernel.!=("") _ -> true end _ -> false end end) _ -> true end end
Example usage:
slot :inner_block @spec heading(assigns :: map()) :: Rendered.t() def heading(assigns) do ~H""" <header :if={not slot_empty?(@inner_block)} class="grid gap-4 pb-8 text-left"> <%= render_slot(@inner_block) %> </header> """ end
Hope this helps.
Top comments (2)
@neophen Make the code in the first case clause look as the code below so the function does not crash when a slot takes a
:let
argument that cannot be nil (because it expects a tuple or a map/structure):An alternative would be to pass a structured argument to the function itself which would then supply it to the
inner_block
function, but that would just be an unnecessary burden for the caller.Thank you, updated the code!