Implementing core components in earlier version of Phoenix without `attr`

Hi everyone, I am trying to implement a custom button in core_components.ex in earlier version of Phoenix. However, I am having trouble implementing as attr function is not available in the earlier versions.

I have facing difficult because without attr and without @rest, I will not be able to pass in other options such as phx-click into my custom button. How can I go around this?

Implementation in newer version

attr(:rest, :global, include: ~w(disabled form name value))
@doc """
  Renders a button.

  ## Examples

      <.button>Send!</.button>
      <.button phx-click="go" class="ml-2">Send!</.button>
  """
  attr(:type, :string, default: nil)
  attr(:class, :string, default: nil)
  attr(:rest, :global, include: ~w(disabled form name value))

  slot(:inner_block, required: true)

  def button(assigns) do
    ~H"""
    <button
      type={@type}
      class={[
        "phx-submit-loading:opacity-75 rounded-lg bg-zinc-900 hover:bg-zinc-700 py-2 px-3",
        "text-sm font-semibold leading-6 text-white active:text-white/80",
        @class
      ]}
      {@rest}
    >
      <%= render_slot(@inner_block) %>
    </button>
    """
  end

Implementation in older version

def button(assigns) do
    assigns =
      assigns
      |> assign_new(:type, fn -> nil end)
      |> assign_new(:class, fn -> nil end)

    ~H"""
    <button
      type={@type}
      class={[
        "phx-submit-loading:opacity-75 rounded-lg bg-zinc-900 hover:bg-zinc-700 py-2 px-3",
        "text-sm font-semibold leading-6 text-white active:text-white/80",
        @class
      ]}
    >
      {@rest}
      <%= render_slot(@inner_block) %>
    </button>
    """
  end

Use assigns_to_attributes.

eg:

def button(assigns) do
  rest = assigns_to_attributes(assigns, [:attributes, :to, :exlude])

  assigns = assign(assigns, :rest, rest)

  ~H"""
  <div {@rest}>
  </div>
  """
end
1 Like

but does this mean we have to hardcode all the possible attributes (e.g. phx-click, disabled etc) that can be passed into button?

Nope, the second argument is a list of assigns you are expecting (basically what you would be declaring with attr).