defmodule RiverConnectWeb.Components.UI.Form do @moduledoc """ Form-related components that help build accessible forms. SaladUI doesn't define its own form component, but instead provides a set of form-related components to enhance the native Phoenix LiveView form. ## Examples: <.form class="space-y-6" for={@form} id="project-form" phx-target={@myself} phx-change="validate" phx-submit="save" > <.form_item> <.form_label>What is your project's name? <.form_control> <.input field={@form[:name]} type="text" phx-debounce="500" /> <.form_description> This is your public display name. <.form_message field={@form[:name]} />
<.button class="btn btn-secondary btn-md" icon="inbox_arrow_down" phx-disable-with="Saving..." > Save project
""" use RiverConnectWeb.Components.UI, :component @doc """ Form item component that acts as a container for a form field. ## Examples: <.form_item> <.form_label>Email <.form_control> <.input field={@form[:email]} type="email" /> <.form_message field={@form[:email]} /> """ attr :class, :string, default: nil slot :inner_block, required: true attr :rest, :global def form_item(assigns) do ~H"""
{render_slot(@inner_block)}
""" end @doc """ Form label component that renders a label for a form field. Shows validation errors through text color when a field has errors. ## Examples: <.form_label>Email <.form_label field={@form[:email]}>Email """ attr :class, :string, default: nil attr :field, Phoenix.HTML.FormField, default: nil, doc: "a form field struct retrieved from the form, for example: @form[:email]" attr :for, :string, default: nil attr :error, :boolean, default: false, doc: "whether the field has an error" slot :inner_block, required: true attr :rest, :global def form_label(assigns) do assigns = assign(assigns, error: assigns[:error] || has_error?(assigns[:field])) ~H""" {render_slot(@inner_block)} """ end @doc """ Form control component that wraps input elements. This is a simple pass-through component that renders its inner block. ## Examples: <.form_control> <.input field={@form[:email]} type="email" /> """ slot :inner_block, required: true def form_control(assigns) do ~H""" {render_slot(@inner_block)} """ end @doc """ Form description component that provides additional context for a form field. ## Examples: <.form_description> We'll only use your email for account-related purposes. """ attr :class, :string, default: nil slot :inner_block, required: true attr :rest, :global def form_description(assigns) do ~H"""

{render_slot(@inner_block)}

""" end @doc """ Form message component that displays validation errors for a form field. ## Examples: <.form_message field={@form[:email]} /> <.form_message> Please enter a valid email address. """ attr :field, Phoenix.HTML.FormField, default: nil, doc: "a form field struct retrieved from the form, for example: @form[:email]" attr :errors, :any, default: [], doc: "a list of error messages to display" attr :class, :string, default: nil slot :inner_block, required: false attr :rest, :global def form_message(assigns) do assigns = assigns |> assign(error: has_error?(assigns[:field]) || not Enum.empty?(assigns[:errors])) |> assign(:message, List.first(assigns[:errors] || field_errors(assigns[:field]))) ~H"""

{msg || @message}

""" end end