{
"files": [
{
"content": "defmodule Shadix.Components.Pagination do\n @moduledoc \"\"\"\n Pagination components translated from the shadcn/ui `pagination` component.\n\n Presentational only; no navigation behavior is wired up. The button-ish\n classes for `pagination_link/1` are lifted verbatim from shadcn's\n `buttonVariants` (base + `outline`/`ghost` variant + `default`/`icon` size).\n \"\"\"\n use Phoenix.Component\n import Shadix.Cn\n\n @button_base \"inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\"\n\n @variant_outline \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50\"\n @variant_ghost \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\"\n\n @sizes %{\n \"default\" => \"h-9 px-4 py-2 has-[>svg]:px-3\",\n \"icon\" => \"size-9\"\n }\n\n attr(:class, :string, default: nil)\n attr(:rest, :global)\n slot(:inner_block, required: true)\n\n def pagination(assigns) do\n class = cn([\"mx-auto flex w-full justify-center\", assigns.class])\n assigns = assign(assigns, :computed_class, class)\n\n ~H\"\"\"\n <nav\n role=\"navigation\"\n aria-label=\"pagination\"\n data-slot=\"pagination\"\n class={@computed_class}\n {@rest}\n >\n {render_slot(@inner_block)}\n </nav>\n \"\"\"\n end\n\n attr(:class, :string, default: nil)\n attr(:rest, :global)\n slot(:inner_block, required: true)\n\n def pagination_content(assigns) do\n class = cn([\"flex flex-row items-center gap-1\", assigns.class])\n assigns = assign(assigns, :computed_class, class)\n\n ~H\"\"\"\n <ul data-slot=\"pagination-content\" class={@computed_class} {@rest}>\n {render_slot(@inner_block)}\n </ul>\n \"\"\"\n end\n\n attr(:class, :string, default: nil)\n attr(:rest, :global)\n slot(:inner_block, required: true)\n\n def pagination_item(assigns) do\n class = cn([assigns.class])\n assigns = assign(assigns, :computed_class, class)\n\n ~H\"\"\"\n <li data-slot=\"pagination-item\" class={@computed_class} {@rest}>\n {render_slot(@inner_block)}\n </li>\n \"\"\"\n end\n\n attr(:class, :string, default: nil)\n attr(:is_active, :boolean, default: false)\n attr(:size, :string, default: \"icon\", values: ~w(default icon))\n attr(:rest, :global, include: ~w(href))\n slot(:inner_block, required: true)\n\n def pagination_link(assigns) do\n variant = if assigns.is_active, do: @variant_outline, else: @variant_ghost\n\n class =\n cn([\n @button_base,\n variant,\n Map.fetch!(@sizes, assigns.size),\n assigns.class\n ])\n\n assigns = assign(assigns, :computed_class, class)\n\n ~H\"\"\"\n <a\n aria-current={if @is_active, do: \"page\"}\n data-slot=\"pagination-link\"\n data-active={to_string(@is_active)}\n class={@computed_class}\n {@rest}\n >\n {render_slot(@inner_block)}\n </a>\n \"\"\"\n end\n\n attr(:class, :string, default: nil)\n attr(:rest, :global, include: ~w(href))\n slot(:inner_block)\n\n def pagination_previous(assigns) do\n class =\n cn([\n @button_base,\n @variant_ghost,\n Map.fetch!(@sizes, \"default\"),\n \"gap-1 px-2.5 sm:pl-2.5\",\n assigns.class\n ])\n\n assigns = assign(assigns, :computed_class, class)\n\n ~H\"\"\"\n <a\n aria-label=\"Go to previous page\"\n data-slot=\"pagination-link\"\n data-active=\"false\"\n class={@computed_class}\n {@rest}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m15 18-6-6 6-6\" />\n </svg>\n <span class=\"hidden sm:block\">Previous</span>\n </a>\n \"\"\"\n end\n\n attr(:class, :string, default: nil)\n attr(:rest, :global, include: ~w(href))\n slot(:inner_block)\n\n def pagination_next(assigns) do\n class =\n cn([\n @button_base,\n @variant_ghost,\n Map.fetch!(@sizes, \"default\"),\n \"gap-1 px-2.5 sm:pr-2.5\",\n assigns.class\n ])\n\n assigns = assign(assigns, :computed_class, class)\n\n ~H\"\"\"\n <a\n aria-label=\"Go to next page\"\n data-slot=\"pagination-link\"\n data-active=\"false\"\n class={@computed_class}\n {@rest}\n >\n <span class=\"hidden sm:block\">Next</span>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n </a>\n \"\"\"\n end\n\n attr(:class, :string, default: nil)\n attr(:rest, :global)\n\n def pagination_ellipsis(assigns) do\n class = cn([\"flex size-9 items-center justify-center\", assigns.class])\n assigns = assign(assigns, :computed_class, class)\n\n ~H\"\"\"\n <span aria-hidden=\"true\" data-slot=\"pagination-ellipsis\" class={@computed_class} {@rest}>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"size-4\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\n <circle cx=\"19\" cy=\"12\" r=\"1\" />\n <circle cx=\"5\" cy=\"12\" r=\"1\" />\n </svg>\n <span class=\"sr-only\">More pages</span>\n </span>\n \"\"\"\n end\nend\n",
"path": "pagination.ex"
}
],
"hooks": [],
"name": "pagination",
"npm_deps": [],
"registry_deps": [
"cn"
]
}