Repository: woylie/flop_phoenix
Pull request #460 (2025-05-03 15:59:29)

previous next attrs
contributes to #411 


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 14ae2bc..80bae9b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,8 +24,9 @@
 - Remove default `class` attributes from pagination component.
 - Remove `role` attribute from the pagination component. The `<nav>` element
   already has the implicit ARIA role `navigation`.
-- Remove `previous_link_content` and `next_link_content` options from pagination
-  component. Use `previous` and `next` slot instead.
+- Remove `previous_link_attrs`, `previous_link_content`, `next_link_attrs`, and
+  `next_link_content` options from pagination component. Use `previous` and
+  `next` slot instead.
 - Remove `ellipsis_attrs` and `ellipsis_content` from the pagination options.
   Use the `ellipsis` slot instead.
 - Remove `current_link_attrs` from pagination options. Use
@@ -35,6 +36,11 @@
 
 ### How to upgrade
 
+The configuration via `pagination_opts` is deprecated. Instead of referencing a
+function that returns the pagination opts, it is recommended to define a
+component that wraps the `Flop.Phoenix.pagination/1` component and sets the
+necessary attributes.
+
 Remove the `wrapper_opts` from your pagination options and pass them directly
 as attributes instead.
 
@@ -53,21 +59,27 @@ as attributes instead.
   />
 ```
 
-Replace the `:previous_link_content` and `next_link_content` attributes with
-the `previous` and `next` slots.
+Replace the `:previous_link_attrs`, `:previous_link_content`, `next_link_attrs`,
+and `next_link_content` attributes with the `previous` and `next` slots.
 
 ```diff
   <Flop.Phoenix.pagination
     meta={@meta}
     path={@path}
     opts={[
+-     previous_link_attrs: [class: "previous"],
 -     previous_link_content: Phoenix.HTML.raw(~s(<i class="fas fa-chevron-left" />)),
+-     next_link_attrs: [class: "next"],
 -     next_link_content: Phoenix.HTML.raw(~s(<i class="fas fa-chevron-right" />))
     ]}
 - />
 + >
-+   <:previous><i class="fas fa-chevron-left" /></:previous>
-+   <:next><i class="fas fa-chevron-right" /></:next>
++   <:previous attrs={[class: "previous"]}>
++     <i class="fas fa-chevron-left" />
++   </:previous>
++   <:next attrs={[class: "next"]}>
++     <i class="fas fa-chevron-right" />
++   </:next>
 + </Flop.Phoenix.pagination>
 ```
 
diff --git a/lib/flop_phoenix.ex b/lib/flop_phoenix.ex
index 4506abd..dea0487 100644
--- a/lib/flop_phoenix.ex
+++ b/lib/flop_phoenix.ex
@@ -33,27 +33,19 @@ defmodule Flop.Phoenix do
         on_paginate={@on_paginate}
         target={@target}
         opts={[
-          next_link_attrs: [class: "next"],
           pagination_link_aria_label: &"\#{&1}ページ目へ",
-          previous_link_attrs: [class: "prev"]
         ]}
-      />
-      \"""
-    end
-
-    defp next_icon do
-      assigns = %{}
-
-      ~H\"""
-      <i class="fas fa-chevron-right"/>
-      \"""
-    end
-
-    defp previous_icon do
-      assigns = %{}
-
-      ~H\"""
-      <i class="fas fa-chevron-left"/>
+      >
+        <:previous attrs={[class: "previous"]}>
+          <i class="fas fa-chevron-left"/>
+        </:previous>
+        <:next attrs={[class: "next"]}>
+          <i class="fas fa-chevron-right"/>
+        </:next>
+        <:ellipsis>
+          <span class="ellipsis">‥</span>
+        </:ellipsis>
+      </Flop.Phoenix.pagination>
       \"""
     end
   end
@@ -149,8 +141,6 @@ defmodule Flop.Phoenix do
   @typedoc """
   Defines the available options for `Flop.Phoenix.pagination/1`.
 
-  - `:next_link_attrs` - The attributes for the link to the next page.
-    Default: `#{inspect(Pagination.default_opts()[:next_link_attrs])}`.
   - `:pagination_link_aria_label` - 1-arity function that takes a page number
     and returns an aria label for the corresponding page link.
     Default: `&"Go to page \#{&1}"`.
@@ -160,16 +150,12 @@ defmodule Flop.Phoenix do
     Default: `#{inspect(Pagination.default_opts()[:pagination_list_attrs])}`.
   - `:pagination_list_item_attrs` - The attributes for the pagination list items.
     Default: `#{inspect(Pagination.default_opts()[:pagination_list_item_attrs])}`.
-  - `:previous_link_attrs` - The attributes for the link to the previous page.
-    Default: `#{inspect(Pagination.default_opts()[:previous_link_attrs])}`.
   """
   @type pagination_option ::
-          {:next_link_attrs, keyword}
-          | {:pagination_link_aria_label, (pos_integer -> binary)}
+          {:pagination_link_aria_label, (pos_integer -> binary)}
           | {:pagination_link_attrs, keyword}
           | {:pagination_list_attrs, keyword}
           | {:pagination_list_item_attrs, keyword}
-          | {:previous_link_attrs, keyword}
 
   @typedoc """
   Defines how many page links to render.
@@ -405,14 +391,30 @@ defmodule Flop.Phoenix do
     The content of the pagination link or button to the previous page.
 
     If the slot is not used, the text "Previous" is rendered.
-    """
+    """ do
+    attr :attrs, :list,
+      doc: """
+      Any additional attributes to add to the link or button.
+
+      Defaults to
+      `[class: "pagination-previous", aria: [label: "Go to previous page"]]`.
+      """
+  end
 
   slot :next,
     doc: """
     The content of the pagination link or button to the next page.
 
     If the slot is not used, the text "Next" is rendered.
-    """
+    """ do
+    attr :attrs, :list,
+      doc: """
+      Any additional attributes to add to the link or button.
+
+      Defaults to
+      `[class: "pagination-next", aria: [label: "Go to next page"]]`.
+      """
+  end
 
   slot :ellipsis,
     doc: """
@@ -431,8 +433,30 @@ defmodule Flop.Phoenix do
     raise Flop.Phoenix.PathOrJSError, component: :pagination
   end
 
-  def pagination(%{opts: opts} = assigns) do
-    assigns = assign(assigns, :opts, Pagination.merge_opts(opts))
+  def pagination(%{opts: opts, previous: previous, next: next} = assigns) do
+    # Unpack previous and next slot attributes. We can't use :for attribute
+    # because the slot is optional.
+    previous_attrs =
+      case previous do
+        [%{attrs: attrs}] ->
+          attrs
+
+        _ ->
+          [class: "pagination-previous", aria: [label: "Go to previous page"]]
+      end
+
+    next_attrs =
+      case next do
+        [%{attrs: attrs}] -> attrs
+        _ -> [class: "pagination-next", aria: [label: "Go to next page"]]
+      end
+
+    assigns =
+      assign(assigns,
+        opts: Pagination.merge_opts(opts),
+        previous_attrs: previous_attrs,
+        next_attrs: next_attrs
+      )
 
     ~H"""
     <.pagination_for
@@ -451,12 +475,9 @@ defmodule Flop.Phoenix do
           path={p.path_fun.(p.previous_page)}
           on_paginate={@on_paginate}
           rel="prev"
-          {@opts[:previous_link_attrs]}
+          {@previous_attrs}
         >
-          {render_slot(@previous)}
-          <%= if @previous == [] do %>
-            Previous
-          <% end %>
+          {render_slot(@previous) || "Previous"}
         </.pagination_link>
         <.pagination_link
           :if={p.pagination_type in [:page, :offset]}
@@ -466,12 +487,9 @@ defmodule Flop.Phoenix do
           path={p.path_fun.(p.next_page)}
           on_paginate={@on_paginate}
           rel="next"
-          {@opts[:next_link_attrs]}
+          {@next_attrs}
         >
-          {render_slot(@next)}
-          <%= if @next == [] do %>
-            Next
-          <% end %>
+          {render_slot(@next) || "Next"}
         </.pagination_link>
         <.page_links
           :if={p.pagination_type in [:page, :offset] and @page_links != :none}
@@ -495,12 +513,9 @@ defmodule Flop.Phoenix do
           target={@target}
           disabled={is_nil(p.previous_cursor)}
           rel="prev"
-          {@opts[:previous_link_attrs]}
+          {@previous_attrs}
         >
-          {render_slot(@previous)}
-          <%= if @previous == [] do %>
-            Previous
-          <% end %>
+          {render_slot(@previous) || "Previous"}
         </.pagination_link>
         <.pagination_link
           :if={p.pagination_type in [:first, :last]}
@@ -510,12 +525,9 @@ defmodule Flop.Phoenix do
           target={@target}
           disabled={is_nil(p.next_cursor)}
           rel="next"
-          {@opts[:next_link_attrs]}
+          {@next_attrs}
         >
-          {render_slot(@next)}
-          <%= if @next == [] do %>
-            Next
-          <% end %>
+          {render_slot(@next) || "Next"}
         </.pagination_link>
       </nav>
     </.pagination_for>
diff --git a/lib/flop_phoenix/pagination.ex b/lib/flop_phoenix/pagination.ex
index b1157c7..998ce87 100644
--- a/lib/flop_phoenix/pagination.ex
+++ b/lib/flop_phoenix/pagination.ex
@@ -268,18 +268,10 @@ defmodule Flop.Phoenix.Pagination do
   @spec default_opts() :: [Flop.Phoenix.pagination_option()]
   def default_opts do
     [
-      next_link_attrs: [
-        aria: [label: "Go to next page"],
-        class: "pagination-next"
-      ],
       pagination_link_aria_label: &"Go to page #{&1}",
       pagination_link_attrs: [class: "pagination-link"],
       pagination_list_attrs: [class: "pagination-list"],
-      pagination_list_item_attrs: [],
-      previous_link_attrs: [
-        aria: [label: "Go to previous page"],
-        class: "pagination-previous"
-      ]
+      pagination_list_item_attrs: []
     ]
   end
 


Test patch:
diff --git a/test/flop_phoenix_test.exs b/test/flop_phoenix_test.exs
index 71e3094..bacbb2a 100644
--- a/test/flop_phoenix_test.exs
+++ b/test/flop_phoenix_test.exs
@@ -294,14 +294,10 @@ defmodule Flop.PhoenixTest do
 
       html =
         parse_heex(~H"""
-        <Flop.Phoenix.pagination
-          meta={@meta}
-          path="/pets"
-          opts={[
-            previous_link_attrs: [class: "prev", title: "p-p-previous"]
-          ]}
-        >
-          <:previous><i class="fas fa-chevron-left" /></:previous>
+        <Flop.Phoenix.pagination meta={@meta} path="/pets">
+          <:previous attrs={[class: "prev", title: "p-p-previous"]}>
+            <i class="fas fa-chevron-left" />
+          </:previous>
         </Flop.Phoenix.pagination>
         """)
 
@@ -352,14 +348,8 @@ defmodule Flop.PhoenixTest do
 
       html =
         parse_heex(~H"""
-        <Flop.Phoenix.pagination
-          meta={@meta}
-          path="/pets"
-          opts={[
-            previous_link_attrs: [class: "prev", title: "no"]
-          ]}
-        >
-          <:previous>Prev</:previous>
+        <Flop.Phoenix.pagination meta={@meta} path="/pets">
+          <:previous attrs={[class: "prev", title: "no"]}>Prev</:previous>
         </Flop.Phoenix.pagination>
         """)
 
@@ -430,14 +420,10 @@ defmodule Flop.PhoenixTest do
 
       html =
         parse_heex(~H"""
-        <Flop.Phoenix.pagination
-          meta={@meta}
-          path="/pets"
-          opts={[
-            next_link_attrs: [class: "next", title: "n-n-next"]
-          ]}
-        >
-          <:next><i class="fas fa-chevron-right" /></:next>
+        <Flop.Phoenix.pagination meta={@meta} path="/pets">
+          <:next attrs={[class: "next", title: "n-n-next"]}>
+            <i class="fas fa-chevron-right" />
+          </:next>
         </Flop.Phoenix.pagination>
         """)
 
@@ -485,14 +471,8 @@ defmodule Flop.PhoenixTest do
 
       html =
         parse_heex(~H"""
-        <Flop.Phoenix.pagination
-          meta={@meta}
-          path="/pets"
-          opts={[
-            next_link_attrs: [class: "next", title: "no"]
-          ]}
-        >
-          <:next>N-n-next</:next>
+        <Flop.Phoenix.pagination meta={@meta} path="/pets">
+          <:next attrs={[class: "next", title: "no"]}>N-n-next</:next>
         </Flop.Phoenix.pagination>
         """)
 
@@ -707,6 +687,7 @@ defmodule Flop.PhoenixTest do
       end
 
       assert previous = find_one(html, "a:fl-contains('Previous')")
+      assert attribute(previous, "aria-label") == "Go to previous page"
       assert attribute(previous, "class") == "pagination-previous"
       assert attribute(previous, "data-phx-link") == "patch"
       assert attribute(previous, "data-phx-link-state") == "push"
@@ -722,6 +703,7 @@ defmodule Flop.PhoenixTest do
       assert_urls_match(href, "/pets", expected_query.(1))
 
       assert next = find_one(html, "a:fl-contains('Next')")
+      assert attribute(next, "aria-label") == "Go to next page"
       assert attribute(next, "class") == "pagination-next"
       assert attribute(next, "data-phx-link") == "patch"
       assert attribute(next, "data-phx-link-state") == "push"
@@ -1286,17 +1268,14 @@ defmodule Flop.PhoenixTest do
     end
 
     test "allows to overwrite previous link attributes and content" do
-      assigns = %{
-        meta: build(:meta_with_cursors),
-        opts: [
-          previous_link_attrs: [class: "prev", title: "p-p-previous"]
-        ]
-      }
+      assigns = %{meta: build(:meta_with_cursors)}
 
       html =
         parse_heex(~H"""
-        <Flop.Phoenix.pagination meta={@meta} path="/pets" opts={@opts}>
-          <:previous><i class="fas fa-chevron-left" /></:previous>
+        <Flop.Phoenix.pagination meta={@meta} path="/pets">
+          <:previous attrs={[class: "prev", title: "p-p-previous"]}>
+            <i class="fas fa-chevron-left" />
+          </:previous>
         </Flop.Phoenix.pagination>
         """)
 
@@ -1347,14 +1326,8 @@ defmodule Flop.PhoenixTest do
 
       html =
         parse_heex(~H"""
-        <Flop.Phoenix.pagination
-          meta={@meta}
-          on_paginate={JS.push("paginate")}
-          opts={[
-            previous_link_attrs: [class: "prev", title: "no"]
-          ]}
-        >
-          <:previous>Prev</:previous>
+        <Flop.Phoenix.pagination meta={@meta} on_paginate={JS.push("paginate")}>
+          <:previous attrs={[class: "prev", title: "no"]}>Prev</:previous>
         </Flop.Phoenix.pagination>
         """)
 
@@ -1421,14 +1394,10 @@ defmodule Flop.PhoenixTest do
 
       html =
         parse_heex(~H"""
-        <Flop.Phoenix.pagination
-          meta={@meta}
-          path="/pets"
-          opts={[
-            next_link_attrs: [class: "next", title: "n-n-next"]
-          ]}
-        >
-          <:next><i class="fas fa-chevron-right" /></:next>
+        <Flop.Phoenix.pagination meta={@meta} path="/pets">
+          <:next attrs={[class: "next", title: "n-n-next"]}>
+            <i class="fas fa-chevron-right" />
+          </:next>
         </Flop.Phoenix.pagination>
         """)
 
@@ -1476,14 +1445,8 @@ defmodule Flop.PhoenixTest do
 
       html =
         parse_heex(~H"""
-        <Flop.Phoenix.pagination
-          meta={@meta}
-          on_paginate={JS.push("paginate")}
-          opts={[
-            next_link_attrs: [class: "next", title: "no"]
-          ]}
-        >
-          <:next>N-n-next</:next>
+        <Flop.Phoenix.pagination meta={@meta} on_paginate={JS.push("pamginate")}>
+          <:next attrs={[class: "next", title: "no"]}>N-n-next</:next>
         </Flop.Phoenix.pagination>
         """)