@linzjs/lui 21.44.2 → 21.44.3

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/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## [21.44.3](https://github.com/linz/lui/compare/v21.44.2...v21.44.3) (2024-08-27)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **LuiPagination:** pagination component improvements ([#1152](https://github.com/linz/lui/issues/1152)) ([139e3e8](https://github.com/linz/lui/commit/139e3e8375b2fa8b92fe262e01d4f59dde1465df))
7
+
1
8
  ## [21.44.2](https://github.com/linz/lui/compare/v21.44.1...v21.44.2) (2024-08-27)
2
9
 
3
10
 
@@ -1,10 +1,23 @@
1
- /// <reference types="react" />
2
1
  import './LuiPagination.scss';
2
+ import React from 'react';
3
3
  declare type PaginationProps = {
4
4
  totalPages: number;
5
5
  currentPage: number;
6
6
  onPageChange: (page: number) => void;
7
7
  isMobileLayout?: boolean | null;
8
+ animate?: boolean;
8
9
  };
9
- export declare const LuiPagination: ({ totalPages, currentPage, onPageChange, isMobileLayout, }: PaginationProps) => JSX.Element;
10
+ /**
11
+ * @description Pagination component for navigating through a list of items with multiple pages.
12
+ * @param currentPage - The currently selected page.
13
+ * @param totalPages - The total number of pages.
14
+ * @param onPageChange - Callback function that is triggered when a new page is selected.
15
+ * It uses the selected page number as an argument.
16
+ * @param isMobileLayout - Optional prop to override the responsive layout.
17
+ * By default, the responsive layout will be used, which shows the full component
18
+ * when the components container is >= 500px, and a mobile layout when < 500px.
19
+ * @param animate - Optional prop to enable or disable the animation when navigating through pages.
20
+ * A panning animation is shown for number values between two ellipsis buttons.
21
+ */
22
+ export declare const LuiPagination: React.ForwardRefExoticComponent<PaginationProps & React.RefAttributes<HTMLDivElement>>;
10
23
  export {};
package/dist/index.js CHANGED
@@ -58458,51 +58458,57 @@ var LuiCounter = React__default["default"].forwardRef(function (props, ref) {
58458
58458
  return (React__default["default"].createElement(React__default["default"].Fragment, null, !(selectedNum === 0 && !countZero) && (React__default["default"].createElement("span", __assign({ ref: ref, className: determineCounterClassname(), "data-testid": "lui-counter-number-".concat(shape), title: title !== null && title !== void 0 ? title : "".concat(selectedNum, " of ").concat(totalNum, " rows selected") }, rest), selectedNum.toLocaleString()))));
58459
58459
  });
58460
58460
 
58461
- var css_248z$8 = "/**\n @deprecated\n */\n/**\n @deprecated\n */\n/**\n @deprecated\n */\n.lui-pagination-override-mobile .lui-pagination-desktop {\n display: none;\n visibility: hidden;\n opacity: 0;\n}\n.lui-pagination-override-mobile .lui-pagination-mobile {\n display: flex;\n}\n\n.lui-pagination-override-desktop .lui-pagination-mobile {\n display: none;\n visibility: hidden;\n opacity: 0;\n}\n.lui-pagination-override-desktop .lui-pagination-desktop {\n display: flex;\n}\n\n.lui-pagination-controller {\n container-type: inline-size;\n}\n@container (min-width: 500px) {\n .lui-pagination-controller .lui-pagination-mobile {\n display: none;\n visibility: hidden;\n opacity: 0;\n }\n .lui-pagination-controller .lui-pagination-desktop {\n display: flex;\n }\n}\n@container (max-width: 499px) {\n .lui-pagination-controller .lui-pagination-desktop {\n display: none;\n visibility: hidden;\n opacity: 0;\n }\n .lui-pagination-controller .lui-pagination-mobile {\n display: flex;\n }\n}\n\n.lui-pagination {\n display: flex;\n user-select: none;\n justify-content: center;\n}\n.lui-pagination-page-counter {\n display: flex;\n align-items: center;\n margin-left: 0.75rem;\n margin-right: 0.75rem;\n}\n.lui-pagination .lui-button {\n color: #2a292c;\n height: 40px;\n padding: 0.5rem 0.75rem;\n vertical-align: top;\n}\n.lui-pagination .lui-button .lui-pagination-navigation-icon {\n padding-top: 1px;\n}\n.lui-pagination .lui-button .lui-pagination-navigation-icon path {\n fill: #2a292c;\n}\n.lui-pagination .lui-button:hover {\n color: #2a292c;\n}\n.lui-pagination .lui-button-selected {\n background-color: #007198;\n color: #ffffff;\n}\n.lui-pagination-ellipsis {\n pointer-events: none;\n}\n.lui-pagination-navigate-disabled {\n pointer-events: none;\n}\n.lui-pagination-navigate-disabled .lui-pagination-navigation-icon {\n padding-top: 1px;\n}\n.lui-pagination-navigate-disabled .lui-pagination-navigation-icon path {\n fill: #989189 !important;\n}";
58461
+ var css_248z$8 = "/**\n @deprecated\n */\n/**\n @deprecated\n */\n/**\n @deprecated\n */\n.lui-pagination-override-mobile .lui-pagination-desktop {\n display: none;\n visibility: hidden;\n opacity: 0;\n}\n.lui-pagination-override-mobile .lui-pagination-mobile {\n display: flex;\n}\n\n.lui-pagination-override-desktop .lui-pagination-mobile {\n display: none;\n visibility: hidden;\n opacity: 0;\n}\n.lui-pagination-override-desktop .lui-pagination-desktop {\n display: flex;\n}\n\n.lui-pagination-controller {\n container-type: inline-size;\n}\n@container (min-width: 500px) {\n .lui-pagination-controller .lui-pagination-mobile {\n display: none;\n visibility: hidden;\n opacity: 0;\n }\n .lui-pagination-controller .lui-pagination-desktop {\n display: flex;\n }\n}\n@container (max-width: 499px) {\n .lui-pagination-controller .lui-pagination-desktop {\n display: none;\n visibility: hidden;\n opacity: 0;\n }\n .lui-pagination-controller .lui-pagination-mobile {\n display: flex;\n }\n}\n\n.lui-pagination {\n display: flex;\n user-select: none;\n justify-content: center;\n}\n.lui-pagination-page-counter {\n display: flex;\n align-items: center;\n margin-left: 0.75rem;\n margin-right: 0.75rem;\n}\n.lui-pagination .lui-button {\n color: #2a292c;\n height: 40px;\n padding: 0.5rem 0.75rem;\n vertical-align: top;\n}\n.lui-pagination .lui-button .lui-pagination-navigation-icon {\n padding-top: 1px;\n}\n.lui-pagination .lui-button .lui-pagination-navigation-icon path {\n fill: #2a292c;\n}\n.lui-pagination .lui-button-selected {\n background-color: #007198;\n color: #ffffff;\n}\n.lui-pagination-ellipsis {\n pointer-events: none;\n}\n.lui-pagination-navigate-disabled {\n pointer-events: none;\n}\n.lui-pagination-navigate-disabled .lui-pagination-navigation-icon {\n padding-top: 1px;\n}\n.lui-pagination-navigate-disabled .lui-pagination-navigation-icon path {\n fill: #989189 !important;\n}\n\n.pan-left {\n transition: transform 0.3s ease-in-out, opacity 0.3s ease-in-out;\n transform: perspective(1000px) rotateY(20deg) translateX(-10px);\n opacity: 0.5;\n}\n\n.pan-right {\n transition: transform 0.3s ease-in-out, opacity 0.3s ease-in-out;\n transform: perspective(1000px) rotateY(-20deg) translateX(10px);\n opacity: 0.5;\n}";
58462
58462
  styleInject(css_248z$8);
58463
58463
 
58464
- var LuiPagination = function (_a) {
58465
- var totalPages = _a.totalPages, currentPage = _a.currentPage, onPageChange = _a.onPageChange, _b = _a.isMobileLayout, isMobileLayout = _b === void 0 ? null : _b;
58464
+ /**
58465
+ * @description Pagination component for navigating through a list of items with multiple pages.
58466
+ * @param currentPage - The currently selected page.
58467
+ * @param totalPages - The total number of pages.
58468
+ * @param onPageChange - Callback function that is triggered when a new page is selected.
58469
+ * It uses the selected page number as an argument.
58470
+ * @param isMobileLayout - Optional prop to override the responsive layout.
58471
+ * By default, the responsive layout will be used, which shows the full component
58472
+ * when the components container is >= 500px, and a mobile layout when < 500px.
58473
+ * @param animate - Optional prop to enable or disable the animation when navigating through pages.
58474
+ * A panning animation is shown for number values between two ellipsis buttons.
58475
+ */
58476
+ var LuiPagination = React.forwardRef(function (_a, ref) {
58477
+ var currentPage = _a.currentPage, totalPages = _a.totalPages, onPageChange = _a.onPageChange, _b = _a.isMobileLayout, isMobileLayout = _b === void 0 ? null : _b, _c = _a.animate, animate = _c === void 0 ? true : _c;
58478
+ var _d = React.useState(null), panDirection = _d[0], setPanDirection = _d[1];
58466
58479
  var visibleCount = 6; // potentially can be refined further, has issues if set to smaller values
58480
+ totalPages = Math.round(totalPages); // Ensure that totalPages is always a whole number
58467
58481
  var mobileLayoutOverride = function () {
58468
- if (isMobileLayout !== null) {
58469
- if (isMobileLayout) {
58482
+ switch (isMobileLayout) {
58483
+ case true:
58470
58484
  return 'lui-pagination-override-mobile';
58471
- }
58472
- else {
58485
+ case false:
58473
58486
  return 'lui-pagination-override-desktop';
58474
- }
58487
+ default:
58488
+ return 'lui-pagination-controller';
58475
58489
  }
58476
- return 'lui-pagination-controller';
58477
- };
58478
- var navigateButtonBefore = function () {
58479
- return (React__default["default"].createElement(LuiButton, { level: "tertiary", key: "lui-pagination-button-navigate-before", className: currentPage > 1
58480
- ? 'lui-pagination-navigate'
58481
- : 'lui-pagination-navigate-disabled', "data-testid": currentPage > 1
58482
- ? 'lui-pagination-navigate-before'
58483
- : 'lui-pagination-navigate-before-disabled', onClick: function () { return handlePaginationPageChange(currentPage - 1); } },
58484
- React__default["default"].createElement(LuiIcon, { name: "ic_keyboard_arrow_left", alt: "Previous page", size: "md", className: "lui-pagination-navigation-icon" })));
58485
- };
58486
- var navigateButtonAfter = function () {
58487
- return (React__default["default"].createElement(LuiButton, { level: "tertiary", key: "lui-pagination-button-navigate-after", className: currentPage < totalPages
58488
- ? 'lui-pagination-navigate'
58489
- : 'lui-pagination-navigate-disabled', "data-testid": currentPage < totalPages
58490
- ? 'lui-pagination-navigate-after'
58491
- : 'lui-pagination-navigate-after-disabled', onClick: function () { return handlePaginationPageChange(currentPage + 1); } },
58492
- React__default["default"].createElement(LuiIcon, { name: "ic_keyboard_arrow_right", alt: "Next page", size: "md", className: "lui-pagination-navigation-icon" })));
58493
58490
  };
58494
58491
  var handlePaginationPageChange = function (pageNumber) {
58495
58492
  if (pageNumber > 0 && pageNumber <= totalPages) {
58496
- // setCurrentPage(pageNumber);
58497
- onPageChange(pageNumber);
58493
+ if (pageNumber > currentPage) {
58494
+ setPanDirection('right');
58495
+ }
58496
+ else if (pageNumber < currentPage) {
58497
+ setPanDirection('left');
58498
+ }
58499
+ else {
58500
+ setPanDirection(null);
58501
+ }
58502
+ setTimeout(function () {
58503
+ setPanDirection(null);
58504
+ onPageChange(pageNumber);
58505
+ }, 300); // Adjust the timeout to match the CSS transition duration
58498
58506
  }
58499
58507
  };
58500
58508
  var renderPaginationNumbers = function () {
58501
58509
  var paginationArray = [];
58502
- // calculate values before and after the currently selected page
58503
58510
  var startPage = Math.max(1, currentPage - 1);
58504
58511
  var endPage = Math.min(totalPages, currentPage + 1);
58505
- // trail pages at the beginning and end if close to the end
58506
58512
  if (currentPage <= visibleCount - 2) {
58507
58513
  startPage = 1;
58508
58514
  endPage = Math.min(totalPages, startPage + visibleCount - 2);
@@ -58511,24 +58517,21 @@ var LuiPagination = function (_a) {
58511
58517
  endPage = totalPages;
58512
58518
  startPage = Math.max(2, endPage - visibleCount + 2);
58513
58519
  }
58514
- // starting page if away from the start
58520
+ paginationArray.push(navigateButtonBefore());
58515
58521
  if (startPage > 1) {
58516
58522
  paginationArray.push(React__default["default"].createElement(LuiButton, { level: "tertiary", key: "lui-pagination-navigation-start", onClick: function () { return handlePaginationPageChange(1); } },
58517
58523
  React__default["default"].createElement("b", null, "1")));
58518
- // add ellipsis if start away from beginning
58519
58524
  if (startPage > 2) {
58520
58525
  paginationArray.push(React__default["default"].createElement(LuiButton, { level: "tertiary", className: "lui-pagination-ellipsis", key: "lui-pagination-ellipsis-start", "data-testid": "lui-pagination-ellipsis" }, '...'));
58521
58526
  }
58522
58527
  }
58523
58528
  var _loop_1 = function (i) {
58524
- paginationArray.push(React__default["default"].createElement(LuiButton, { level: "tertiary", key: "lui-pagination-button-".concat(i), className: i === currentPage ? 'lui-button-selected' : '', onClick: function () { return handlePaginationPageChange(i); } },
58529
+ paginationArray.push(React__default["default"].createElement(LuiButton, { level: "tertiary", key: "lui-pagination-button-".concat(i), className: "".concat(i === currentPage ? 'lui-button-selected' : ''), onClick: function () { return handlePaginationPageChange(i); } },
58525
58530
  React__default["default"].createElement("b", null, i)));
58526
58531
  };
58527
- // add all the visible page numbers
58528
58532
  for (var i = startPage; i <= endPage; i++) {
58529
58533
  _loop_1(i);
58530
58534
  }
58531
- // show ellipsis if away from the end
58532
58535
  if (endPage < totalPages) {
58533
58536
  if (endPage < totalPages - 1) {
58534
58537
  paginationArray.push(React__default["default"].createElement(LuiButton, { level: "tertiary", className: "lui-pagination-ellipsis", key: "lui-pagination-ellipsis-end", "data-testid": "lui-pagination-ellipsis" }, '...'));
@@ -58536,12 +58539,45 @@ var LuiPagination = function (_a) {
58536
58539
  paginationArray.push(React__default["default"].createElement(LuiButton, { level: "tertiary", key: "lui-pagination-button-last", onClick: function () { return handlePaginationPageChange(totalPages); } },
58537
58540
  React__default["default"].createElement("b", null, totalPages)));
58538
58541
  }
58539
- // add back and forward icons to the beginning and end
58540
- paginationArray.unshift(navigateButtonBefore());
58541
58542
  paginationArray.push(navigateButtonAfter());
58542
- return paginationArray;
58543
+ var ellipsisStart = -1;
58544
+ var ellipsisEnd = -1;
58545
+ paginationArray.forEach(function (button, index) {
58546
+ if (button.props.children === '...') {
58547
+ if (ellipsisStart === -1) {
58548
+ ellipsisStart = index;
58549
+ }
58550
+ else {
58551
+ ellipsisEnd = index;
58552
+ }
58553
+ }
58554
+ });
58555
+ return paginationArray.map(function (button, index) {
58556
+ if (index > ellipsisStart && index < ellipsisEnd) {
58557
+ return React__default["default"].cloneElement(button, {
58558
+ className: "".concat(button.props.className, " ").concat(panDirection && animate ? "pan-".concat(panDirection) : '')
58559
+ });
58560
+ }
58561
+ return button;
58562
+ });
58563
+ };
58564
+ var navigateButtonBefore = function () {
58565
+ return (React__default["default"].createElement(LuiButton, { level: "tertiary", key: "lui-pagination-button-navigate-before", className: currentPage > 1
58566
+ ? 'lui-pagination-navigate'
58567
+ : 'lui-pagination-navigate-disabled', "data-testid": currentPage > 1
58568
+ ? 'lui-pagination-navigate-before'
58569
+ : 'lui-pagination-navigate-before-disabled', onClick: function () { return handlePaginationPageChange(currentPage - 1); } },
58570
+ React__default["default"].createElement(LuiIcon, { name: "ic_keyboard_arrow_left", alt: "Previous page", size: "md", className: "lui-pagination-navigation-icon" })));
58543
58571
  };
58544
- return (React__default["default"].createElement("div", { className: mobileLayoutOverride() },
58572
+ var navigateButtonAfter = function () {
58573
+ return (React__default["default"].createElement(LuiButton, { level: "tertiary", key: "lui-pagination-button-navigate-after", className: currentPage < totalPages
58574
+ ? 'lui-pagination-navigate'
58575
+ : 'lui-pagination-navigate-disabled', "data-testid": currentPage < totalPages
58576
+ ? 'lui-pagination-navigate-after'
58577
+ : 'lui-pagination-navigate-after-disabled', onClick: function () { return handlePaginationPageChange(currentPage + 1); } },
58578
+ React__default["default"].createElement(LuiIcon, { name: "ic_keyboard_arrow_right", alt: "Next page", size: "md", className: "lui-pagination-navigation-icon" })));
58579
+ };
58580
+ return (React__default["default"].createElement("div", { className: mobileLayoutOverride(), ref: ref },
58545
58581
  (mobileLayoutOverride() === 'lui-pagination-override-mobile' ||
58546
58582
  mobileLayoutOverride() === 'lui-pagination-controller') && (React__default["default"].createElement("div", { className: "lui-pagination-mobile lui-pagination" },
58547
58583
  React__default["default"].createElement(React__default["default"].Fragment, null,
@@ -58567,7 +58603,7 @@ var LuiPagination = function (_a) {
58567
58603
  (mobileLayoutOverride() === 'lui-pagination-override-desktop' ||
58568
58604
  mobileLayoutOverride() === 'lui-pagination-controller') && (React__default["default"].createElement("div", { className: "lui-pagination-desktop lui-pagination" },
58569
58605
  React__default["default"].createElement("div", { className: "pagination" }, renderPaginationNumbers())))));
58570
- };
58606
+ });
58571
58607
 
58572
58608
  var css_248z$7 = "/**\n @deprecated\n */\n/**\n @deprecated\n */\n/**\n @deprecated\n */\n.Separator {\n background-color: #eaeaea;\n position: absolute;\n display: flex;\n justify-content: space-around;\n transition-property: background-color;\n transition-delay: 750ms;\n transition-duration: 0ms;\n}\n.Separator-arrows {\n align-self: center;\n position: relative;\n opacity: 0;\n transition-property: opacity;\n transition-delay: 750ms;\n transition-duration: 0ms;\n}\n.Separator:focus-within, .Separator:hover, .Separator:focus, .Separator:active {\n background-color: #73c8e1;\n transition-delay: 0ms;\n transition-duration: 0ms;\n}\n.Separator:focus-within .Separator-arrows, .Separator:hover .Separator-arrows, .Separator:focus .Separator-arrows, .Separator:active .Separator-arrows {\n opacity: 1;\n transition-delay: 0ms;\n transition-duration: 0ms;\n display: inline-block;\n}";
58573
58609
  styleInject(css_248z$7);