defmodule MalarkeyWeb.Components.UI do @moduledoc """ Shadcn-inspired UI components for Malarkey. These components follow the shadcn/ui design system adapted for Phoenix LiveView. """ use Phoenix.Component @doc """ Renders a button with shadcn styling. ## Examples <.ui_button>Click me <.ui_button variant="outline">Outlined <.ui_button variant="ghost">Ghost <.ui_button size="lg">Large button """ attr :variant, :string, default: "default", values: ~w(default outline ghost destructive) attr :size, :string, default: "default", values: ~w(default sm lg icon) attr :class, :any, default: nil attr :rest, :global, include: ~w(disabled type phx-click phx-disable-with phx-value-id phx-value-content) slot :inner_block, required: true def ui_button(assigns) do ~H""" """ end defp variant_classes("default"), do: "bg-primary text-primary-foreground shadow hover:bg-primary/90" defp variant_classes("outline"), do: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground" defp variant_classes("ghost"), do: "hover:bg-accent hover:text-accent-foreground" defp variant_classes("destructive"), do: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90" defp size_classes("default"), do: "h-9 px-4 py-2" defp size_classes("sm"), do: "h-8 rounded-md px-3 text-xs" defp size_classes("lg"), do: "h-10 rounded-md px-8" defp size_classes("icon"), do: "h-9 w-9" @doc """ Renders a shadcn-styled input field. """ attr :id, :any, default: nil attr :name, :any attr :label, :string, default: nil attr :value, :any attr :type, :string, default: "text" attr :class, :string, default: nil attr :field, Phoenix.HTML.FormField, doc: "a form field struct retrieved from the form" attr :errors, :list, default: [] attr :checked, :boolean, doc: "the checked flag for checkbox inputs" attr :prompt, :string, default: nil, doc: "the prompt for select inputs" attr :options, :list, doc: "the options to pass to Phoenix.HTML.Form.options_for_select/2" attr :multiple, :boolean, default: false, doc: "the multiple flag for select inputs" attr :rest, :global, include: ~w(accept autocomplete capture cols disabled form list max maxlength min minlength multiple pattern placeholder readonly required rows size step) slot :inner_block def ui_input(%{field: %Phoenix.HTML.FormField{} = field} = assigns) do assigns |> assign(field: nil, id: assigns.id || field.id) |> assign(:errors, Enum.map(field.errors, &translate_error(&1))) |> assign_new(:name, fn -> if assigns.multiple, do: field.name <> "[]", else: field.name end) |> assign_new(:value, fn -> field.value end) |> ui_input() end def ui_input(%{type: "checkbox"} = assigns) do assigns = assign_new(assigns, :checked, fn -> Phoenix.HTML.Form.normalize_value("checkbox", assigns[:value]) end) ~H"""
<%= render_slot(@inner_block) %>
""" end @doc """ Renders a shadcn-styled card. """ attr :id, :string, default: nil attr :class, :string, default: nil attr :rest, :global slot :inner_block, required: true def ui_card(assigns) do ~H"""<%= render_slot(@inner_block) %>
""" end @doc """ Renders a card content area. """ attr :class, :string, default: nil slot :inner_block, required: true def ui_card_content(assigns) do ~H"""