@uktrade/react-component-library 0.22.16 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/ApiQuery/ApiProvider.d.ts +3 -3
- package/dist/components/NotificationBanner/NotificationBanner.module.css +2 -2
- package/dist/components/Pagination/Pagination.d.ts +9 -0
- package/dist/components/Pagination/Pagination.d.ts.map +1 -0
- package/dist/components/Pagination/Pagination.js +41 -0
- package/dist/components/Tabs/Tabs.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/package.json +3 -3
- package/src/components/NotificationBanner/NotificationBanner.module.css +2 -2
- package/src/components/Pagination/Pagination.tsx +147 -0
- package/src/components/Tabs/Tabs.tsx +1 -1
- package/src/index.ts +1 -0
|
@@ -12,13 +12,13 @@ export type ApiQueryState<T> = {
|
|
|
12
12
|
refetch: () => void;
|
|
13
13
|
};
|
|
14
14
|
export declare function useApi<T>(key: QueryKey, queryFn: () => Promise<T>): {
|
|
15
|
-
query: import("@tanstack/react-query").UseQueryResult<
|
|
15
|
+
query: import("@tanstack/react-query").UseQueryResult<T, Error>;
|
|
16
16
|
state: {
|
|
17
|
-
data:
|
|
17
|
+
data: T | undefined;
|
|
18
18
|
isLoading: boolean;
|
|
19
19
|
isError: boolean;
|
|
20
20
|
error: Error | null;
|
|
21
|
-
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<
|
|
21
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<T, Error>>;
|
|
22
22
|
};
|
|
23
23
|
};
|
|
24
24
|
export declare function useApiMutation<TData, TVariables = void>(mutationFn: (variables: TVariables) => Promise<TData>): {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type React from "react";
|
|
2
|
+
interface PaginationProps {
|
|
3
|
+
currentPage: number;
|
|
4
|
+
totalPages: number;
|
|
5
|
+
onPageChange: (page: number) => void;
|
|
6
|
+
}
|
|
7
|
+
export declare const Pagination: ({ currentPage, totalPages, onPageChange }: PaginationProps) => React.JSX.Element;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=Pagination.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Pagination.d.ts","sourceRoot":"","sources":["../../../src/components/Pagination/Pagination.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,UAAU,eAAe;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAID,eAAO,MAAM,UAAU,GAAI,2CAA2C,eAAe,KAAG,KAAK,CAAC,GAAG,CAAC,OAsIjG,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
const MAX_PAGES = 200;
|
|
4
|
+
export const Pagination = ({ currentPage, totalPages, onPageChange }) => {
|
|
5
|
+
const safeTotalPages = Math.min(totalPages, MAX_PAGES);
|
|
6
|
+
const getPageNumbers = () => {
|
|
7
|
+
const pages = [];
|
|
8
|
+
// Always show first page
|
|
9
|
+
pages.push(1);
|
|
10
|
+
const start = Math.max(2, currentPage - 1);
|
|
11
|
+
const end = Math.min(safeTotalPages - 1, currentPage + 1);
|
|
12
|
+
// Ellipsis after first page
|
|
13
|
+
if (start > 2) {
|
|
14
|
+
pages.push("...");
|
|
15
|
+
}
|
|
16
|
+
// Pages around current
|
|
17
|
+
for (let i = start; i <= end; i++) {
|
|
18
|
+
pages.push(i);
|
|
19
|
+
}
|
|
20
|
+
// Ellipsis before last page
|
|
21
|
+
if (end < safeTotalPages - 1) {
|
|
22
|
+
pages.push("...");
|
|
23
|
+
}
|
|
24
|
+
// Always show last page if more than 1
|
|
25
|
+
if (safeTotalPages > 1) {
|
|
26
|
+
pages.push(safeTotalPages);
|
|
27
|
+
}
|
|
28
|
+
return pages;
|
|
29
|
+
};
|
|
30
|
+
const pages = getPageNumbers();
|
|
31
|
+
return (_jsxs("nav", { className: "govuk-pagination", "aria-label": "Pagination", style: { justifyContent: "center" }, "data-testid": "pagination", children: [currentPage > 1 && (_jsx("div", { className: "govuk-pagination__prev", children: _jsxs("a", { className: "govuk-link govuk-pagination__link", href: "#", rel: "prev", onClick: (e) => {
|
|
32
|
+
e.preventDefault();
|
|
33
|
+
onPageChange(currentPage - 1);
|
|
34
|
+
}, children: [_jsx("svg", { className: "govuk-pagination__icon govuk-pagination__icon--prev", xmlns: "http://www.w3.org/2000/svg", height: "13", width: "15", "aria-hidden": "true", focusable: "false", viewBox: "0 0 15 13", children: _jsx("path", { d: "m6.5938-0.0078125-6.7266 6.7266 6.7441 6.4062 1.377-1.449-4.1856-3.9768h12.896v-2h-12.984l4.2931-4.293-1.414-1.414z" }) }), _jsxs("span", { className: "govuk-pagination__link-title", children: ["Previous", _jsx("span", { className: "govuk-visually-hidden", children: " page" })] })] }) })), _jsx("ul", { className: "govuk-pagination__list", children: pages.map((page) => (_jsx("li", { className: `govuk-pagination__item${page === currentPage ? " govuk-pagination__item--current" : ""}`, children: typeof page === "number" ? (_jsx("a", { className: "govuk-link govuk-pagination__link", href: "#", "aria-label": `Page ${page}`, "aria-current": page === currentPage ? "page" : undefined, onClick: (e) => {
|
|
35
|
+
e.preventDefault();
|
|
36
|
+
onPageChange(page);
|
|
37
|
+
}, children: page })) : (_jsx("span", { className: "govuk-pagination__link-title", "aria-hidden": "true", children: page })) }, page))) }), currentPage < safeTotalPages && (_jsx("div", { className: "govuk-pagination__next", children: _jsxs("a", { className: "govuk-link govuk-pagination__link", href: "#", rel: "next", onClick: (e) => {
|
|
38
|
+
e.preventDefault();
|
|
39
|
+
onPageChange(currentPage + 1);
|
|
40
|
+
}, children: [_jsxs("span", { className: "govuk-pagination__link-title", children: ["Next", _jsx("span", { className: "govuk-visually-hidden", children: " page" })] }), _jsx("svg", { className: "govuk-pagination__icon govuk-pagination__icon--next", xmlns: "http://www.w3.org/2000/svg", height: "13", width: "15", "aria-hidden": "true", focusable: "false", viewBox: "0 0 15 13", children: _jsx("path", { d: "m8.107-0.0078125-1.4136 1.414 4.2926 4.293h-12.986v2h12.896l-4.1855 3.9766 1.377 1.4492 6.7441-6.4062-6.7246-6.7266z" }) })] }) }))] }));
|
|
41
|
+
};
|
|
@@ -7,7 +7,7 @@ export const Tabs = ({ tabs, title = "Contents", onTabChange, activeTabId, }) =>
|
|
|
7
7
|
}
|
|
8
8
|
// Determine active tab, fallback to first tab
|
|
9
9
|
const currentActiveId = activeTabId || tabs[0].id;
|
|
10
|
-
return (_jsxs("div", { className: "govuk-tabs", "data-module": "govuk-tabs", children: [_jsx("h2", { className: "govuk-tabs__title", children: title }), _jsx("ul", { className: "govuk-tabs__list", children: tabs.map((tab) => (_jsx("li", { className: clsx("govuk-tabs__list-item", tab.id === currentActiveId && "govuk-tabs__list-item--selected"), children: _jsx("a", { className: "govuk-tabs__tab", href: `#${tab.id}`, onClick: (
|
|
10
|
+
return (_jsxs("div", { className: "govuk-tabs", "data-module": "govuk-tabs", children: [_jsx("h2", { className: "govuk-tabs__title", children: title }), _jsx("ul", { className: "govuk-tabs__list", children: tabs.map((tab) => (_jsx("li", { className: clsx("govuk-tabs__list-item", tab.id === currentActiveId && "govuk-tabs__list-item--selected"), children: _jsx("a", { className: "govuk-tabs__tab", href: `#${tab.id}`, onClick: () => {
|
|
11
11
|
onTabChange?.(tab.id);
|
|
12
12
|
}, children: tab.label }) }, tab.id))) }), tabs.map((tab) => (_jsx("div", { id: tab.id, className: clsx("govuk-tabs__panel", tab.id !== currentActiveId && "govuk-tabs__panel--hidden"), children: tab.content }, tab.id)))] }));
|
|
13
13
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -17,4 +17,5 @@ export * from "./components/Details/Details";
|
|
|
17
17
|
export * from "./components/Tooltip/Tooltip";
|
|
18
18
|
export * from "./components/Tabs/Tabs";
|
|
19
19
|
export * from "./components/Table/Table";
|
|
20
|
+
export * from "./components/Pagination/Pagination";
|
|
20
21
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sCAAsC,CAAC;AACrD,cAAc,sCAAsC,CAAC;AACrD,cAAc,wCAAwC,CAAC;AACvD,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,4CAA4C,CAAC;AAC3D,cAAc,sCAAsC,CAAC;AACrD,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oDAAoD,CAAC;AACnE,cAAc,8BAA8B,CAAC;AAC7C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sCAAsC,CAAC;AACrD,cAAc,sCAAsC,CAAC;AACrD,cAAc,wCAAwC,CAAC;AACvD,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,4CAA4C,CAAC;AAC3D,cAAc,sCAAsC,CAAC;AACrD,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oDAAoD,CAAC;AACnE,cAAc,8BAA8B,CAAC;AAC7C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,oCAAoC,CAAC"}
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uktrade/react-component-library",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"description": "A collection of reusable React components following GOV.UK design patterns.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -68,8 +68,8 @@
|
|
|
68
68
|
"vitest": "^4.0.18"
|
|
69
69
|
},
|
|
70
70
|
"engines": {
|
|
71
|
-
"npm": ">=11.
|
|
72
|
-
"node": ">=24.
|
|
71
|
+
"npm": ">=11.17.0",
|
|
72
|
+
"node": ">=24.19.0"
|
|
73
73
|
},
|
|
74
74
|
"dependencies": {
|
|
75
75
|
"@tanstack/react-query": "^5.90.20",
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import type React from "react";
|
|
4
|
+
|
|
5
|
+
interface PaginationProps {
|
|
6
|
+
currentPage: number;
|
|
7
|
+
totalPages: number;
|
|
8
|
+
onPageChange: (page: number) => void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const MAX_PAGES = 200;
|
|
12
|
+
|
|
13
|
+
export const Pagination = ({ currentPage, totalPages, onPageChange }: PaginationProps): React.JSX.Element => {
|
|
14
|
+
const safeTotalPages = Math.min(totalPages, MAX_PAGES);
|
|
15
|
+
|
|
16
|
+
const getPageNumbers = () => {
|
|
17
|
+
const pages: (number | string)[] = [];
|
|
18
|
+
|
|
19
|
+
// Always show first page
|
|
20
|
+
pages.push(1);
|
|
21
|
+
|
|
22
|
+
const start = Math.max(2, currentPage - 1);
|
|
23
|
+
const end = Math.min(safeTotalPages - 1, currentPage + 1);
|
|
24
|
+
|
|
25
|
+
// Ellipsis after first page
|
|
26
|
+
if (start > 2) {
|
|
27
|
+
pages.push("...");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Pages around current
|
|
31
|
+
for (let i = start; i <= end; i++) {
|
|
32
|
+
pages.push(i);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Ellipsis before last page
|
|
36
|
+
if (end < safeTotalPages - 1) {
|
|
37
|
+
pages.push("...");
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Always show last page if more than 1
|
|
41
|
+
if (safeTotalPages > 1) {
|
|
42
|
+
pages.push(safeTotalPages);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return pages;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const pages = getPageNumbers();
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<nav
|
|
52
|
+
className="govuk-pagination"
|
|
53
|
+
aria-label="Pagination"
|
|
54
|
+
style={{ justifyContent: "center" }}
|
|
55
|
+
data-testid="pagination"
|
|
56
|
+
>
|
|
57
|
+
{/* Previous */}
|
|
58
|
+
{currentPage > 1 && (
|
|
59
|
+
<div className="govuk-pagination__prev">
|
|
60
|
+
<a
|
|
61
|
+
className="govuk-link govuk-pagination__link"
|
|
62
|
+
href="#"
|
|
63
|
+
rel="prev"
|
|
64
|
+
onClick={(e) => {
|
|
65
|
+
e.preventDefault();
|
|
66
|
+
onPageChange(currentPage - 1);
|
|
67
|
+
}}
|
|
68
|
+
>
|
|
69
|
+
<svg
|
|
70
|
+
className="govuk-pagination__icon govuk-pagination__icon--prev"
|
|
71
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
72
|
+
height="13"
|
|
73
|
+
width="15"
|
|
74
|
+
aria-hidden="true"
|
|
75
|
+
focusable="false"
|
|
76
|
+
viewBox="0 0 15 13"
|
|
77
|
+
>
|
|
78
|
+
<path d="m6.5938-0.0078125-6.7266 6.7266 6.7441 6.4062 1.377-1.449-4.1856-3.9768h12.896v-2h-12.984l4.2931-4.293-1.414-1.414z" />
|
|
79
|
+
</svg>
|
|
80
|
+
<span className="govuk-pagination__link-title">
|
|
81
|
+
Previous<span className="govuk-visually-hidden"> page</span>
|
|
82
|
+
</span>
|
|
83
|
+
</a>
|
|
84
|
+
</div>
|
|
85
|
+
)}
|
|
86
|
+
|
|
87
|
+
{/* Page numbers */}
|
|
88
|
+
<ul className="govuk-pagination__list">
|
|
89
|
+
{pages.map((page) => (
|
|
90
|
+
<li
|
|
91
|
+
key={page}
|
|
92
|
+
className={`govuk-pagination__item${page === currentPage ? " govuk-pagination__item--current" : ""}`}
|
|
93
|
+
>
|
|
94
|
+
{typeof page === "number" ? (
|
|
95
|
+
<a
|
|
96
|
+
className="govuk-link govuk-pagination__link"
|
|
97
|
+
href="#"
|
|
98
|
+
aria-label={`Page ${page}`}
|
|
99
|
+
aria-current={page === currentPage ? "page" : undefined}
|
|
100
|
+
onClick={(e) => {
|
|
101
|
+
e.preventDefault();
|
|
102
|
+
onPageChange(page);
|
|
103
|
+
}}
|
|
104
|
+
>
|
|
105
|
+
{page}
|
|
106
|
+
</a>
|
|
107
|
+
) : (
|
|
108
|
+
<span className="govuk-pagination__link-title" aria-hidden="true">
|
|
109
|
+
{page}
|
|
110
|
+
</span>
|
|
111
|
+
)}
|
|
112
|
+
</li>
|
|
113
|
+
))}
|
|
114
|
+
</ul>
|
|
115
|
+
|
|
116
|
+
{/* Next */}
|
|
117
|
+
{currentPage < safeTotalPages && (
|
|
118
|
+
<div className="govuk-pagination__next">
|
|
119
|
+
<a
|
|
120
|
+
className="govuk-link govuk-pagination__link"
|
|
121
|
+
href="#"
|
|
122
|
+
rel="next"
|
|
123
|
+
onClick={(e) => {
|
|
124
|
+
e.preventDefault();
|
|
125
|
+
onPageChange(currentPage + 1);
|
|
126
|
+
}}
|
|
127
|
+
>
|
|
128
|
+
<span className="govuk-pagination__link-title">
|
|
129
|
+
Next<span className="govuk-visually-hidden"> page</span>
|
|
130
|
+
</span>
|
|
131
|
+
<svg
|
|
132
|
+
className="govuk-pagination__icon govuk-pagination__icon--next"
|
|
133
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
134
|
+
height="13"
|
|
135
|
+
width="15"
|
|
136
|
+
aria-hidden="true"
|
|
137
|
+
focusable="false"
|
|
138
|
+
viewBox="0 0 15 13"
|
|
139
|
+
>
|
|
140
|
+
<path d="m8.107-0.0078125-1.4136 1.414 4.2926 4.293h-12.986v2h12.896l-4.1855 3.9766 1.377 1.4492 6.7441-6.4062-6.7246-6.7266z" />
|
|
141
|
+
</svg>
|
|
142
|
+
</a>
|
|
143
|
+
</div>
|
|
144
|
+
)}
|
|
145
|
+
</nav>
|
|
146
|
+
);
|
|
147
|
+
};
|
package/src/index.ts
CHANGED