Working with Sibling Components

From ElixirBlocks
Revision as of 14:44, 12 March 2025 by Admin (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
defmodule Heading do
  use Phoenix.Component

  def head(assigns) do
    ~H"""
    <ul>
      <%= for heading <- @headings do %>
        <li phx-click="append_content" phx-value-heading={heading}>{heading}!</li>
      <% end %>
    </ul>
    """
  end
end

#________________________________________________________________
defmodule Content do
  use Phoenix.Component

  def content(assigns) do
    ~H"""
    <p>This is content: {@content}!</p>
    """
  end
end
#________________________________________________________________

defmodule AppWeb.PageLive do
  use AppWeb, :live_view
  import Heading
  import Content

  def mount(_params, _session, socket) do
    {:ok, assign(socket, content: "This is some great content here")}
  end

  def headings do
    ["one", "two", "three"]
  end

  def render(assigns) do
    ~H"""
    <Heading.head headings={headings()} />
    <Content.content content={@content} />
    """
  end

  def handle_event("append_content", %{"heading" => _heading}, socket) do
    updated_content = socket.assigns.content <> " hello there"
    {:noreply, assign(socket, content: updated_content)}
  end
end


defmodule AppWeb.PageLive do
  use AppWeb, :live_view
  import Phoenix.Component

  defmodule Heading do
    use Phoenix.Component

    def head(assigns) do
      click_handler = assigns[:click_handler] || "append_content" # Default to "append_content" if not passed
      ~H"""
      <ul>
        <%= for heading <- @headings do %>
          <li phx-click={click_handler} phx-value-heading={heading}>{heading}!</li>
        <% end %>
      </ul>
      """
    end
  end

  defmodule Content do
    use Phoenix.Component

    def content(assigns) do
      ~H"""
      <p>This is content: {@content}!</p>
      """
    end
  end

  def mount(_params, _session, socket) do
    {:ok, assign(socket, content: "This is some great content here")}
  end

  def headings do
    ["one", "two", "three"]
  end

  def render(assigns) do
    # Pass the desired function name as `click_handler` (you can pass any string you want)
    ~H"""
    <Heading.head headings={headings()} click_handler="custom_action" />
    <Content.content content={@content} />
    """
  end

  # Default handler for "append_content"
  def handle_event("append_content", %{"heading" => _heading}, socket) do
    updated_content = socket.assigns.content <> " hello there"
    {:noreply, assign(socket, content: updated_content)}
  end

  # Custom handler for a different function
  def handle_event("custom_action", %{"heading" => _heading}, socket) do
    updated_content = socket.assigns.content <> " custom action triggered!"
    {:noreply, assign(socket, content: updated_content)}
  end
end