@eztrak/shared 0.4.0 → 0.4.5

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/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
- export { HandleApiErrorOptions, RtkQueryError, capitalizeText, checkIfExistsInArray, cn, convertCommaDataToArray, currencyFormatter, deserializeJson, flattenTableData, formatDate, formatDateTime, formatValidationErrorsHtml, getApiError, getErrorMessages, getFieldsByCategory, getFieldsByInputType, getFieldsByName, handleApiError, isEmpty, normalizeApiListItems, parseCurrencyValueToNumber, removeByPropertyValues, toDateInputValue, toLowerCaseText, truncateText } from './utils/index.mjs';
1
+ export { ConfirmationAlertOptions, HandleApiErrorOptions, RtkQueryError, capitalizeText, checkIfExistsInArray, cn, confirmationAlert, convertCommaDataToArray, currencyFormatter, deserializeJson, flattenTableData, formatDate, formatDateTime, formatValidationErrorsHtml, getApiError, getErrorMessages, getFieldsByCategory, getFieldsByInputType, getFieldsByName, handleApiError, isEmpty, normalizeApiListItems, parseCurrencyValueToNumber, removeByPropertyValues, toDateInputValue, toLowerCaseText, truncateText } from './utils/index.mjs';
2
2
  export { UseGridHeightOptions, useGridHeight, usePaginationUrlSync } from './hooks/index.mjs';
3
- export { EztrakTab, EztrakTabs, EztrakTabsClassNames, EztrakTabsProps } from './components/index.mjs';
3
+ export { CustomPagination, CustomPaginationClassNames, CustomPaginationProps, EztrakTab, EztrakTabs, EztrakTabsClassNames, EztrakTabsProps, LayoutStatus, PaginationData, ResetColumnsButton, ResetColumnsButtonProps, TableLayoutToolbarControls, TableLayoutToolbarControlsProps } from './components/index.mjs';
4
4
  import 'clsx';
5
5
  import 'react-router-dom';
6
6
  import 'react';
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- export { HandleApiErrorOptions, RtkQueryError, capitalizeText, checkIfExistsInArray, cn, convertCommaDataToArray, currencyFormatter, deserializeJson, flattenTableData, formatDate, formatDateTime, formatValidationErrorsHtml, getApiError, getErrorMessages, getFieldsByCategory, getFieldsByInputType, getFieldsByName, handleApiError, isEmpty, normalizeApiListItems, parseCurrencyValueToNumber, removeByPropertyValues, toDateInputValue, toLowerCaseText, truncateText } from './utils/index.js';
1
+ export { ConfirmationAlertOptions, HandleApiErrorOptions, RtkQueryError, capitalizeText, checkIfExistsInArray, cn, confirmationAlert, convertCommaDataToArray, currencyFormatter, deserializeJson, flattenTableData, formatDate, formatDateTime, formatValidationErrorsHtml, getApiError, getErrorMessages, getFieldsByCategory, getFieldsByInputType, getFieldsByName, handleApiError, isEmpty, normalizeApiListItems, parseCurrencyValueToNumber, removeByPropertyValues, toDateInputValue, toLowerCaseText, truncateText } from './utils/index.js';
2
2
  export { UseGridHeightOptions, useGridHeight, usePaginationUrlSync } from './hooks/index.js';
3
- export { EztrakTab, EztrakTabs, EztrakTabsClassNames, EztrakTabsProps } from './components/index.js';
3
+ export { CustomPagination, CustomPaginationClassNames, CustomPaginationProps, EztrakTab, EztrakTabs, EztrakTabsClassNames, EztrakTabsProps, LayoutStatus, PaginationData, ResetColumnsButton, ResetColumnsButtonProps, TableLayoutToolbarControls, TableLayoutToolbarControlsProps } from './components/index.js';
4
4
  import 'clsx';
5
5
  import 'react-router-dom';
6
6
  import 'react';
package/dist/index.js CHANGED
@@ -30,10 +30,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var src_exports = {};
32
32
  __export(src_exports, {
33
+ CustomPagination: () => CustomPagination,
33
34
  EztrakTabs: () => EztrakTabs,
35
+ ResetColumnsButton: () => ResetColumnsButton,
36
+ TableLayoutToolbarControls: () => TableLayoutToolbarControls,
34
37
  capitalizeText: () => capitalizeText,
35
38
  checkIfExistsInArray: () => checkIfExistsInArray,
36
39
  cn: () => cn,
40
+ confirmationAlert: () => confirmationAlert,
37
41
  convertCommaDataToArray: () => convertCommaDataToArray,
38
42
  currencyFormatter: () => currencyFormatter,
39
43
  deserializeJson: () => deserializeJson,
@@ -299,6 +303,21 @@ function handleApiError(error, { showAlert = false, fallbackMessage } = {}) {
299
303
  const message = fallbackMessage || data?.message || data?.title || error.error || "An error occurred. Please try again.";
300
304
  import_react_hot_toast.default.error(message);
301
305
  }
306
+ function confirmationAlert(onConfirm, options = {}) {
307
+ void import_sweetalert2.default.fire({
308
+ title: options.title ?? "Are you sure?",
309
+ text: options.text,
310
+ icon: options.icon ?? "warning",
311
+ showCancelButton: true,
312
+ confirmButtonText: options.confirmButtonText ?? "Yes",
313
+ cancelButtonText: options.cancelButtonText ?? "Cancel",
314
+ confirmButtonColor: "#FF7335"
315
+ }).then((result) => {
316
+ if (result.isConfirmed) {
317
+ onConfirm();
318
+ }
319
+ });
320
+ }
302
321
 
303
322
  // src/hooks/usePaginationUrlSync.ts
304
323
  var import_react = require("react");
@@ -463,86 +482,93 @@ function EztrakTabs({
463
482
  classNames?.wrapper,
464
483
  className
465
484
  );
466
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: wrapperClass, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "eztrak-tabs-container", children: [
467
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("nav", { className: "eztrak-tabs-nav", "aria-label": "Tabs", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
468
- "ul",
485
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: wrapperClass, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: cn("eztrak-tabs-container", classNames?.container), children: [
486
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
487
+ "nav",
469
488
  {
470
- role: "tablist",
471
- className: cn("eztrak-tabs-list", classNames?.list),
472
- onKeyDown: handleListKeyDown,
473
- children: tabs.map((tab) => {
474
- const isActive = displayActive === tab.id;
475
- const tabId = `${baseId}-tab-${tab.id}`;
476
- const panelId = `${baseId}-panel-${tab.id}`;
477
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
478
- "li",
479
- {
480
- role: "presentation",
481
- className: cn(
482
- "eztrak-tabs-item",
483
- isActive && "eztrak-tabs-item-active",
484
- classNames?.item,
485
- isActive && classNames?.itemActive
486
- ),
487
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
488
- "button",
489
+ className: cn("eztrak-tabs-nav", classNames?.nav),
490
+ "aria-label": "Tabs",
491
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
492
+ "ul",
493
+ {
494
+ role: "tablist",
495
+ className: cn("eztrak-tabs-list", classNames?.list),
496
+ onKeyDown: handleListKeyDown,
497
+ children: tabs.map((tab) => {
498
+ const isActive = displayActive === tab.id;
499
+ const tabId = `${baseId}-tab-${tab.id}`;
500
+ const panelId = `${baseId}-panel-${tab.id}`;
501
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
502
+ "li",
489
503
  {
490
- ref: (el) => {
491
- if (el) {
492
- tabRefs.current.set(tab.id, el);
493
- } else {
494
- tabRefs.current.delete(tab.id);
495
- }
496
- },
497
- type: "button",
498
- role: "tab",
499
- id: tabId,
500
- "aria-selected": isActive,
501
- "aria-controls": showPanels ? panelId : void 0,
502
- tabIndex: isActive ? 0 : -1,
503
- disabled: tab.disabled,
504
+ role: "presentation",
504
505
  className: cn(
505
- "eztrak-tabs-button",
506
- isActive && "eztrak-tabs-button-active",
507
- classNames?.button,
508
- isActive && classNames?.buttonActive
506
+ "eztrak-tabs-item",
507
+ isActive && "eztrak-tabs-item-active",
508
+ classNames?.item,
509
+ isActive && classNames?.itemActive
509
510
  ),
510
- onClick: () => handleTabClick(tab.id, tab.disabled),
511
- children: [
512
- tab.icon ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
513
- "span",
514
- {
515
- className: cn("eztrak-tabs-icon", classNames?.icon),
516
- "aria-hidden": true,
517
- children: tab.icon
518
- }
519
- ) : null,
520
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
521
- "span",
522
- {
523
- className: cn("eztrak-tabs-label", classNames?.label),
524
- children: tab.label
525
- }
526
- ),
527
- isActive ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
528
- "span",
529
- {
530
- className: cn(
531
- "eztrak-tabs-underline",
532
- classNames?.underline
511
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
512
+ "button",
513
+ {
514
+ ref: (el) => {
515
+ if (el) {
516
+ tabRefs.current.set(tab.id, el);
517
+ } else {
518
+ tabRefs.current.delete(tab.id);
519
+ }
520
+ },
521
+ type: "button",
522
+ role: "tab",
523
+ id: tabId,
524
+ "aria-selected": isActive,
525
+ "aria-controls": showPanels ? panelId : void 0,
526
+ tabIndex: isActive ? 0 : -1,
527
+ disabled: tab.disabled,
528
+ className: cn(
529
+ "eztrak-tabs-button",
530
+ isActive && "eztrak-tabs-button-active",
531
+ classNames?.button,
532
+ isActive && classNames?.buttonActive
533
+ ),
534
+ onClick: () => handleTabClick(tab.id, tab.disabled),
535
+ children: [
536
+ tab.icon ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
537
+ "span",
538
+ {
539
+ className: cn("eztrak-tabs-icon", classNames?.icon),
540
+ "aria-hidden": true,
541
+ children: tab.icon
542
+ }
543
+ ) : null,
544
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
545
+ "span",
546
+ {
547
+ className: cn("eztrak-tabs-label", classNames?.label),
548
+ children: tab.label
549
+ }
533
550
  ),
534
- "aria-hidden": true
535
- }
536
- ) : null
537
- ]
538
- }
539
- )
540
- },
541
- tab.id
542
- );
543
- })
551
+ isActive ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
552
+ "span",
553
+ {
554
+ className: cn(
555
+ "eztrak-tabs-underline",
556
+ classNames?.underline
557
+ ),
558
+ "aria-hidden": true
559
+ }
560
+ ) : null
561
+ ]
562
+ }
563
+ )
564
+ },
565
+ tab.id
566
+ );
567
+ })
568
+ }
569
+ )
544
570
  }
545
- ) }),
571
+ ),
546
572
  showPanels ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: cn("eztrak-tabs-content", classNames?.content), children: tabs.map((tab) => {
547
573
  const isActive = displayActive === tab.id;
548
574
  const panelId = `${baseId}-panel-${tab.id}`;
@@ -565,12 +591,332 @@ function EztrakTabs({
565
591
  }) }) : null
566
592
  ] }) });
567
593
  }
594
+
595
+ // src/components/pagination/CustomPagination.tsx
596
+ var import_react_router_dom = require("react-router-dom");
597
+ var import_jsx_runtime2 = require("react/jsx-runtime");
598
+ var DEFAULT_PAGE_SIZE_OPTIONS = [10, 20, 30, 50, 100];
599
+ function padCount(num) {
600
+ return num.toString().padStart(2, "0");
601
+ }
602
+ function RefreshIcon({
603
+ size = 14,
604
+ className
605
+ }) {
606
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
607
+ "svg",
608
+ {
609
+ width: size,
610
+ height: size,
611
+ viewBox: "0 0 24 24",
612
+ fill: "none",
613
+ stroke: "currentColor",
614
+ strokeWidth: "2",
615
+ strokeLinecap: "round",
616
+ strokeLinejoin: "round",
617
+ "aria-hidden": "true",
618
+ className,
619
+ children: [
620
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8" }),
621
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M21 3v5h-5" }),
622
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16" }),
623
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M8 16H3v5" })
624
+ ]
625
+ }
626
+ );
627
+ }
628
+ function ResetColumnsButton({
629
+ onReset,
630
+ disabled = false,
631
+ isLoading = false
632
+ }) {
633
+ const handleClick = () => {
634
+ confirmationAlert(onReset, {
635
+ text: "Reset column order, widths, and visibility to defaults?",
636
+ icon: "warning",
637
+ title: "Reset column layout to default"
638
+ });
639
+ };
640
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
641
+ "button",
642
+ {
643
+ type: "button",
644
+ onClick: handleClick,
645
+ disabled: disabled || isLoading,
646
+ title: "Reset column layout to default",
647
+ className: "inline-flex items-center gap-1.5 rounded-xl border border-primary-150 bg-white px-3 py-1.5 text-sm font-medium text-primary-150 hover:bg-gray-50 focus:outline-none disabled:hover:bg-white",
648
+ children: [
649
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RefreshIcon, { size: 14, className: cn(isLoading ? "animate-spin" : "") }),
650
+ "Reset columns"
651
+ ]
652
+ }
653
+ );
654
+ }
655
+ function TableLayoutToolbarControls({
656
+ layoutStatus = {},
657
+ onResetLayout,
658
+ renderResetControl,
659
+ isLoading = false
660
+ }) {
661
+ const { isLayoutLoading, isLayoutSaving, isLayoutResetting } = layoutStatus;
662
+ const isLayoutBusy = isLayoutLoading || isLayoutSaving || isLayoutResetting;
663
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex items-center gap-3", children: onResetLayout && (renderResetControl ? renderResetControl(onResetLayout) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
664
+ ResetColumnsButton,
665
+ {
666
+ onReset: onResetLayout,
667
+ disabled: isLayoutBusy,
668
+ isLoading
669
+ }
670
+ )) });
671
+ }
672
+ function CustomPagination({
673
+ paginationData,
674
+ paginationPageSize,
675
+ pageSizeOptions: pageSizeOptionsProp,
676
+ isLoading = false,
677
+ paramNames,
678
+ onPageChange,
679
+ onPageSizeChange,
680
+ onResetLayout,
681
+ renderResetControl,
682
+ layoutStatus,
683
+ classNames,
684
+ className
685
+ }) {
686
+ const [searchParams, setSearchParams] = (0, import_react_router_dom.useSearchParams)();
687
+ const pageKey = paramNames?.page ?? "page";
688
+ const perPageKey = paramNames?.perPage ?? "perPage";
689
+ const pageSizeOptions = pageSizeOptionsProp ?? paginationPageSize ?? DEFAULT_PAGE_SIZE_OPTIONS;
690
+ const currentPage = paginationData ? Math.max(0, paginationData.currentPage - 1) : 0;
691
+ const handlePageChange = (pageNumber) => {
692
+ if (!paginationData || pageNumber < 0 || pageNumber >= paginationData.pageCount) {
693
+ return;
694
+ }
695
+ const safePage = Math.max(
696
+ 1,
697
+ Math.min(pageNumber + 1, paginationData.pageCount)
698
+ );
699
+ const newParams = new URLSearchParams(searchParams);
700
+ newParams.set(pageKey, String(safePage));
701
+ setSearchParams(newParams, { replace: true });
702
+ onPageChange?.(safePage);
703
+ };
704
+ const handlePageSizeChange = (event) => {
705
+ const parsed = parseInt(event.target.value, 10);
706
+ if (!Number.isFinite(parsed) || parsed < 1) {
707
+ return;
708
+ }
709
+ const newParams = new URLSearchParams(searchParams);
710
+ newParams.set(pageKey, "1");
711
+ newParams.set(perPageKey, String(parsed));
712
+ setSearchParams(newParams, { replace: true });
713
+ onPageSizeChange?.(parsed);
714
+ };
715
+ const createPageButtons = () => {
716
+ const buttons = [];
717
+ const maxButtons = 5;
718
+ const totalPages = Math.max(1, paginationData?.pageCount ?? 1);
719
+ let startPage = Math.max(0, currentPage - Math.floor(maxButtons / 2));
720
+ let endPage = Math.min(totalPages - 1, startPage + maxButtons - 1);
721
+ if (endPage - startPage + 1 < maxButtons) {
722
+ startPage = Math.max(0, endPage - maxButtons + 1);
723
+ }
724
+ if (startPage > 0) {
725
+ buttons.push(
726
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
727
+ "button",
728
+ {
729
+ type: "button",
730
+ onClick: () => handlePageChange(0),
731
+ "aria-label": "Page 1",
732
+ className: cn(
733
+ "px-3 py-2 text-sm text-gray-600 hover:text-blue-600 hover:bg-blue-50 rounded-md transition-colors",
734
+ classNames?.pageButton
735
+ ),
736
+ children: "1"
737
+ },
738
+ "1"
739
+ )
740
+ );
741
+ if (startPage > 1) {
742
+ buttons.push(
743
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
744
+ "span",
745
+ {
746
+ "aria-hidden": "true",
747
+ className: "px-2 py-2 text-gray-400",
748
+ children: "..."
749
+ },
750
+ "ellipsis1"
751
+ )
752
+ );
753
+ }
754
+ }
755
+ for (let i = startPage; i <= endPage; i++) {
756
+ const isActive = currentPage === i;
757
+ buttons.push(
758
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
759
+ "button",
760
+ {
761
+ type: "button",
762
+ onClick: () => handlePageChange(i),
763
+ "aria-label": `Page ${i + 1}`,
764
+ "aria-current": isActive ? "page" : void 0,
765
+ className: cn(
766
+ "px-3 py-2 text-sm rounded-md transition-colors",
767
+ isActive ? cn("bg-gray-400 text-white", classNames?.activePageButton) : cn(
768
+ "text-gray-600 hover:text-gray-600 hover:bg-gray-50",
769
+ classNames?.pageButton
770
+ )
771
+ ),
772
+ children: i + 1
773
+ },
774
+ i + 1
775
+ )
776
+ );
777
+ }
778
+ if (endPage < totalPages - 1) {
779
+ if (endPage < totalPages - 2) {
780
+ buttons.push(
781
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
782
+ "span",
783
+ {
784
+ "aria-hidden": "true",
785
+ className: "px-2 py-2 text-gray-400",
786
+ children: "..."
787
+ },
788
+ "ellipsis2"
789
+ )
790
+ );
791
+ }
792
+ buttons.push(
793
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
794
+ "button",
795
+ {
796
+ type: "button",
797
+ onClick: () => handlePageChange(totalPages - 1),
798
+ "aria-label": `Page ${totalPages}`,
799
+ className: cn(
800
+ "px-3 py-2 text-sm text-gray-600 hover:text-gray-600 hover:bg-gray-50 rounded-md transition-colors",
801
+ classNames?.pageButton
802
+ ),
803
+ children: totalPages
804
+ },
805
+ totalPages
806
+ )
807
+ );
808
+ }
809
+ return buttons;
810
+ };
811
+ if (isLoading || !paginationData) {
812
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex items-center justify-center p-6 bg-gray-50", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-gray-500", children: isLoading ? "Loading..." : "No pagination data" }) });
813
+ }
814
+ const effectiveSizeOptions = pageSizeOptions.includes(paginationData.perPage) ? pageSizeOptions : [...pageSizeOptions, paginationData.perPage].sort((a, b) => a - b);
815
+ const startItem = paginationData.totalCount === 0 ? 0 : (paginationData.currentPage - 1) * paginationData.perPage + 1;
816
+ const endItem = Math.min(
817
+ startItem + paginationData.perPage - 1,
818
+ paginationData.totalCount
819
+ );
820
+ const { isLayoutLoading, isLayoutSaving, isLayoutResetting } = layoutStatus ?? {};
821
+ const isLayoutBusy = isLayoutLoading || isLayoutSaving || isLayoutResetting;
822
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
823
+ "div",
824
+ {
825
+ className: cn(
826
+ "flex items-center justify-between pb-4",
827
+ className,
828
+ classNames?.root
829
+ ),
830
+ children: [
831
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: cn("flex-1", classNames?.info), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "text-xs font-medium text-neutral-400", children: [
832
+ "Showing ",
833
+ padCount(startItem),
834
+ " - ",
835
+ padCount(endItem),
836
+ " of",
837
+ " ",
838
+ paginationData.totalCount ?? 0,
839
+ " results"
840
+ ] }) }),
841
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
842
+ "nav",
843
+ {
844
+ "aria-label": "Pagination",
845
+ className: cn("flex items-center space-x-1", classNames?.nav),
846
+ children: [
847
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
848
+ "button",
849
+ {
850
+ type: "button",
851
+ onClick: () => handlePageChange(currentPage - 1),
852
+ disabled: currentPage === 0,
853
+ className: "p-2 text-gray-400 hover:text-gray-600 disabled:opacity-30 disabled:cursor-not-allowed transition-colors",
854
+ "aria-label": "Previous page",
855
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M10.7 2.3a1 1 0 0 1 0 1.4L6.4 8l4.3 4.3a1 1 0 1 1-1.4 1.4l-5-5a1 1 0 0 1 0-1.4l5-5a1 1 0 0 1 1.4 0z" }) })
856
+ }
857
+ ),
858
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex items-center space-x-1", children: createPageButtons() }),
859
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
860
+ "button",
861
+ {
862
+ type: "button",
863
+ onClick: () => handlePageChange(currentPage + 1),
864
+ disabled: currentPage >= paginationData.pageCount - 1,
865
+ className: "p-2 text-gray-400 hover:text-gray-600 disabled:opacity-30 disabled:cursor-not-allowed transition-colors",
866
+ "aria-label": "Next page",
867
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M5.3 13.7a1 1 0 0 1 0-1.4L9.6 8 5.3 3.7a1 1 0 0 1 1.4-1.4l5 5a1 1 0 0 1 0 1.4l-5 5a1 1 0 0 1-1.4 0z" }) })
868
+ }
869
+ )
870
+ ]
871
+ }
872
+ ),
873
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex-1 flex justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-center gap-3", children: [
874
+ onResetLayout && (renderResetControl ? renderResetControl(onResetLayout) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
875
+ ResetColumnsButton,
876
+ {
877
+ onReset: onResetLayout,
878
+ disabled: isLayoutBusy,
879
+ isLoading
880
+ }
881
+ )),
882
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-center space-x-2", children: [
883
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
884
+ "label",
885
+ {
886
+ htmlFor: "pagination-per-page",
887
+ className: "text-sm text-gray-600",
888
+ children: "Items per page"
889
+ }
890
+ ),
891
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
892
+ "select",
893
+ {
894
+ id: "pagination-per-page",
895
+ value: paginationData.perPage || 10,
896
+ onChange: handlePageSizeChange,
897
+ className: cn(
898
+ "px-3 py-1.5 text-sm border border-gray-300 rounded-md bg-white text-gray-700 hover:border-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors",
899
+ classNames?.select
900
+ ),
901
+ children: effectiveSizeOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("option", { value: option, children: option }, option))
902
+ }
903
+ )
904
+ ] })
905
+ ] }) })
906
+ ]
907
+ }
908
+ );
909
+ }
568
910
  // Annotate the CommonJS export names for ESM import in node:
569
911
  0 && (module.exports = {
912
+ CustomPagination,
570
913
  EztrakTabs,
914
+ ResetColumnsButton,
915
+ TableLayoutToolbarControls,
571
916
  capitalizeText,
572
917
  checkIfExistsInArray,
573
918
  cn,
919
+ confirmationAlert,
574
920
  convertCommaDataToArray,
575
921
  currencyFormatter,
576
922
  deserializeJson,