diff --git a/CHANGELOG.md b/CHANGELOG.md
index 618694e..486a1b9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
+### Fix
+
+- paging when displayed inside a form.
+
+### Added
+
+- possibility to customize back/next first/last page navigation components.
+
### Removed
- remove cypress declarations
diff --git a/cypress/cypress/component/Paging/Paging.cy.tsx b/cypress/cypress/component/Paging/Paging.cy.tsx
index 9404959..0ede16e 100644
--- a/cypress/cypress/component/Paging/Paging.cy.tsx
+++ b/cypress/cypress/component/Paging/Paging.cy.tsx
@@ -100,4 +100,59 @@ describe("Paging.cy.tsx", () => {
.replace("{total}", (pages * itemsPerPage).toString()),
);
});
+
+ it("custom navigationComponents work correctly", () => {
+ const itemsPerPage = 10;
+ const pages = 5;
+ const currentPage = 3;
+ const translations = { showedItemsText: "Item {from} to {to} from {total}", itemsPerPageDropdown: "Items per page" };
+ const customNavigationComponents = {
+ backPageComponent: "←",
+ nextPageComponent: "→",
+ firstPageComponent: "⇤",
+ lastPageComponent: "⇥",
+ };
+
+ mount(
+ ,
+ );
+
+ // Check that custom navigation components are rendered
+ cy.get("[data-cy-root] > .container-fluid > .row > .col-6:nth-of-type(2) > .btn-group > button.btn").then(
+ (items: JQuery) => {
+ // Verify custom symbols are present
+ cy.wrap(items.filter((_, item) => item.textContent === "⇤"))
+ .should("exist")
+ .and("be.visible");
+ cy.wrap(items.filter((_, item) => item.textContent === "←"))
+ .should("exist")
+ .and("be.visible");
+ cy.wrap(items.filter((_, item) => item.textContent === "→"))
+ .should("exist")
+ .and("be.visible");
+ cy.wrap(items.filter((_, item) => item.textContent === "⇥"))
+ .should("exist")
+ .and("be.visible");
+
+ // Test functionality with custom components
+ cy.wrap(items.filter((_, item) => item.textContent === "⇤")).click();
+ cy.get("@setCurrentPage").should("be.calledWith", 1);
+ cy.wrap(items.filter((_, item) => item.textContent === "←")).click();
+ cy.get("@setCurrentPage").should("be.calledWith", currentPage - 1);
+ cy.wrap(items.filter((_, item) => item.textContent === "→")).click();
+ cy.get("@setCurrentPage").should("be.calledWith", currentPage + 1);
+ cy.wrap(items.filter((_, item) => item.textContent === "⇥")).click();
+ cy.get("@setCurrentPage").should("be.calledWith", pages);
+ },
+ );
+ });
});
diff --git a/src/lib/Paging/Paging.tsx b/src/lib/Paging/Paging.tsx
index 469f0dc..6714a12 100644
--- a/src/lib/Paging/Paging.tsx
+++ b/src/lib/Paging/Paging.tsx
@@ -1,5 +1,5 @@
import { Button, ButtonGroup, Col, DropdownItem, DropdownMenu, DropdownToggle, Row, UncontrolledButtonDropdown } from "reactstrap";
-import { useMemo } from "react";
+import { ReactNode, useMemo } from "react";
interface PagingProps {
currentItemsPerPage: number;
@@ -8,6 +8,7 @@ interface PagingProps {
currentRecordCount: number;
pagingPossible?: boolean;
translations: PagingTranslations;
+ navigationComponents?: PagingNavigationComponents;
possiblePageItemCounts?: number[];
maxPagesShown?: number;
showControls?: boolean;
@@ -21,6 +22,20 @@ interface PagingTranslations {
itemsPerPageDropdown: string;
}
+interface PagingNavigationComponents {
+ backPageComponent: ReactNode;
+ nextPageComponent: ReactNode;
+ firstPageComponent: ReactNode;
+ lastPageComponent: ReactNode;
+}
+
+const defaultNavigationComponents: PagingNavigationComponents = {
+ backPageComponent: "<",
+ nextPageComponent: ">",
+ firstPageComponent: "<<",
+ lastPageComponent: ">>",
+};
+
// eslint-disable-next-line complexity
const Paging = ({
currentItemsPerPage,
@@ -29,6 +44,7 @@ const Paging = ({
currentRecordCount,
pagingPossible = true,
translations,
+ navigationComponents = defaultNavigationComponents,
possiblePageItemCounts,
maxPagesShown = 7,
showControls = true,
@@ -36,6 +52,7 @@ const Paging = ({
setItemsPerPage,
setCurrentPage,
}: PagingProps) => {
+ const { backPageComponent, nextPageComponent, firstPageComponent, lastPageComponent } = navigationComponents;
const maxPage = Math.ceil(totalRecords / currentItemsPerPage);
const firstPageShown = Math.max(0, Math.min(currentPage - Math.ceil(maxPagesShown / 2), maxPage - maxPagesShown));
@@ -79,12 +96,12 @@ const Paging = ({
{showControls && (
)}
{showControls && (
)}
{Array.from({ length: maxPage + 1 }, (_, i) => i)
@@ -97,12 +114,12 @@ const Paging = ({
))}
{showControls && (
)}
{showControls && (
)}
@@ -113,4 +130,4 @@ const Paging = ({
);
};
-export { Paging, PagingProps, PagingTranslations };
+export { Paging, PagingProps, PagingTranslations, PagingNavigationComponents };
diff --git a/styles/Form/_form.scss b/styles/Form/_form.scss
index 87fa4bb..ae14c8c 100644
--- a/styles/Form/_form.scss
+++ b/styles/Form/_form.scss
@@ -1,4 +1,4 @@
-form div[role="group"] {
+form div[role="group"]:not(.paging div[role="group"]) {
display: flex;
gap: 0.25rem;