defmodule Phoenix.UI.Components.Select do @moduledoc """ Provides select component. """ alias Phoenix.HTML.Form import Phoenix.UI.Components.{ErrorTag, FormGroup, HelperText, Heroicon, Label} use Phoenix.UI, :component attr(:"phx-debounce", :any, default: "blur") attr(:"phx-feedback-for", :string) attr(:end_icon, :map, default: nil, doc: "Heroicon-specific attrs to use, such as `name`.") attr(:errors, :list) attr(:extend_class, :string, doc: "Extend existing classes applied to the component.") attr(:field, :any, doc: "a %Phoenix.HTML.Form{}/field name tuple, for example: {f, :email}") attr(:full_width, :boolean, default: false) attr(:helper_text, :string, default: nil) attr(:id, :any) attr(:label, :string, default: nil) attr(:margin, :string, default: "normal", values: ["dense", "none", "normal"]) attr(:multiple, :boolean, default: false, doc: "the multiple flag for selects") attr(:name, :any) attr(:options, :list, doc: "the options to pass to Phoenix.HTML.Form.options_for_select/2") attr(:prompt, :string, default: nil, doc: "the prompt for selects") attr(:rest, :global, include: ~w(autocomplete disabled form max maxlength min minlength pattern placeholder readonly required size step) ) attr(:start_icon, :map, default: nil, doc: "Heroicon-specific attrs to use, such as `name`.") attr(:type, :string, default: "text") attr(:value, :any) attr(:variant, :string, default: "simple", values: ["simple", "solid", "underline", "unstyled"]) @doc """ Renders select component. ## Examples ``` <.select /> ``` """ @spec select(Socket.assigns()) :: Rendered.t() def select(%{field: {f, field}} = assigns) do assigns = assigns |> assign(field: nil) |> assign_class(~w( select appearance-none block py-2 pr-12 text-slate-700 dark:text-slate-300 text-base outline-none focus:outline-none placeholder-slate-400 dark:placeholder-slate-600 transition-all ease-in-out duration-200 #{classes(:background, assigns)} #{classes(:end_icon, assigns)} #{classes(:rounded, assigns)} #{classes(:start_icon, assigns)} #{classes(:variant, assigns)} #{classes(:width, assigns)} )) |> assign_new(:"phx-feedback-for", fn -> Form.input_name(f, field) end) |> assign_new(:errors, fn -> translate_errors(f.errors || [], field) end) |> assign_new(:id, fn -> Form.input_id(f, field) end) |> assign_new(:name, fn -> Form.input_name(f, field) end) |> assign_new(:value, fn -> Form.input_value(f, field) end) ~H""" <.form_group margin={@margin} invalid={Enum.any?(@errors)} phx-feedback-for={assigns[:"phx-feedback-for"]} > <.label :if={@label} for={@id}><%= @label %>