@eztrak/shared 0.6.9 → 0.7.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/{chunk-HANZBMA7.mjs → chunk-J6FBBM4R.mjs} +144 -24
- package/dist/chunk-J6FBBM4R.mjs.map +1 -0
- package/dist/components/index.d.mts +19 -2
- package/dist/components/index.d.ts +19 -2
- package/dist/components/index.js +140 -23
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +3 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +140 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -1
- package/package.json +1 -1
- package/dist/chunk-HANZBMA7.mjs.map +0 -1
package/dist/components/index.js
CHANGED
|
@@ -36,6 +36,7 @@ __export(components_exports, {
|
|
|
36
36
|
Modal: () => Modal,
|
|
37
37
|
ResetColumnsButton: () => ResetColumnsButton,
|
|
38
38
|
ResetFiltersButton: () => ResetFiltersButton,
|
|
39
|
+
SearchInput: () => SearchInput,
|
|
39
40
|
TableLayoutToolbarControls: () => TableLayoutToolbarControls
|
|
40
41
|
});
|
|
41
42
|
module.exports = __toCommonJS(components_exports);
|
|
@@ -661,17 +662,132 @@ function ResetFiltersButton({
|
|
|
661
662
|
);
|
|
662
663
|
}
|
|
663
664
|
|
|
665
|
+
// src/components/search-filters/SearchInput.tsx
|
|
666
|
+
var import_react2 = require("react");
|
|
667
|
+
var import_fi = require("react-icons/fi");
|
|
668
|
+
var import_react_router_dom3 = require("react-router-dom");
|
|
669
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
670
|
+
function SearchInput({
|
|
671
|
+
placeholder = "Search...",
|
|
672
|
+
searchBtn = "",
|
|
673
|
+
searchClassName = "",
|
|
674
|
+
searchWrapperClass = "",
|
|
675
|
+
searchIconClassName = "",
|
|
676
|
+
defaultParam = "query",
|
|
677
|
+
showIcon = true,
|
|
678
|
+
name = "search",
|
|
679
|
+
type = "search",
|
|
680
|
+
liveSearch = false,
|
|
681
|
+
debounceDelay = 500,
|
|
682
|
+
customIcon = null,
|
|
683
|
+
defaultValue,
|
|
684
|
+
...props
|
|
685
|
+
}) {
|
|
686
|
+
const [searchParams, setSearchParams] = (0, import_react_router_dom3.useSearchParams)();
|
|
687
|
+
const queryParam = searchParams.get(defaultParam) || defaultValue || "";
|
|
688
|
+
const [inputValue, setInputValue] = (0, import_react2.useState)(queryParam);
|
|
689
|
+
const debounceTimerRef = (0, import_react2.useRef)(null);
|
|
690
|
+
const updateSearchParams = (searchQuery) => {
|
|
691
|
+
if (searchQuery?.trim()) {
|
|
692
|
+
setSearchParams((prev) => {
|
|
693
|
+
prev.set(defaultParam, searchQuery.trim());
|
|
694
|
+
return prev;
|
|
695
|
+
});
|
|
696
|
+
} else {
|
|
697
|
+
setSearchParams((prev) => {
|
|
698
|
+
prev.delete(defaultParam);
|
|
699
|
+
return prev;
|
|
700
|
+
});
|
|
701
|
+
}
|
|
702
|
+
};
|
|
703
|
+
const handleSearch = (e) => {
|
|
704
|
+
e.preventDefault();
|
|
705
|
+
const formData = new FormData(e.currentTarget);
|
|
706
|
+
const searchQuery = formData.get(name);
|
|
707
|
+
updateSearchParams(String(searchQuery ?? ""));
|
|
708
|
+
};
|
|
709
|
+
const handleInputChange = (e) => {
|
|
710
|
+
const value = e.target.value;
|
|
711
|
+
setInputValue(value);
|
|
712
|
+
if (liveSearch) {
|
|
713
|
+
if (debounceTimerRef.current) {
|
|
714
|
+
clearTimeout(debounceTimerRef.current);
|
|
715
|
+
}
|
|
716
|
+
debounceTimerRef.current = setTimeout(() => {
|
|
717
|
+
updateSearchParams(value);
|
|
718
|
+
}, debounceDelay);
|
|
719
|
+
}
|
|
720
|
+
if (value === "") {
|
|
721
|
+
if (debounceTimerRef.current) {
|
|
722
|
+
clearTimeout(debounceTimerRef.current);
|
|
723
|
+
}
|
|
724
|
+
setInputValue("");
|
|
725
|
+
updateSearchParams("");
|
|
726
|
+
}
|
|
727
|
+
};
|
|
728
|
+
(0, import_react2.useEffect)(() => {
|
|
729
|
+
setInputValue(queryParam);
|
|
730
|
+
}, [queryParam]);
|
|
731
|
+
(0, import_react2.useEffect)(() => {
|
|
732
|
+
return () => {
|
|
733
|
+
if (debounceTimerRef.current) {
|
|
734
|
+
clearTimeout(debounceTimerRef.current);
|
|
735
|
+
}
|
|
736
|
+
};
|
|
737
|
+
}, []);
|
|
738
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
739
|
+
"form",
|
|
740
|
+
{
|
|
741
|
+
onSubmit: handleSearch,
|
|
742
|
+
className: cn(
|
|
743
|
+
"flex items-center justify-between bg-white rounded-md px-2 h-11",
|
|
744
|
+
searchWrapperClass
|
|
745
|
+
),
|
|
746
|
+
children: [
|
|
747
|
+
showIcon && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
748
|
+
"button",
|
|
749
|
+
{
|
|
750
|
+
type: "submit",
|
|
751
|
+
className: cn(
|
|
752
|
+
"bg-white text-secondary rounded-full flex items-center justify-center w-10 h-10",
|
|
753
|
+
searchBtn
|
|
754
|
+
),
|
|
755
|
+
children: customIcon ? customIcon : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
756
|
+
import_fi.FiSearch,
|
|
757
|
+
{
|
|
758
|
+
className: cn("h-5 w-5 text-gray-400", searchIconClassName)
|
|
759
|
+
}
|
|
760
|
+
)
|
|
761
|
+
}
|
|
762
|
+
),
|
|
763
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
764
|
+
"input",
|
|
765
|
+
{
|
|
766
|
+
value: inputValue,
|
|
767
|
+
onChange: handleInputChange,
|
|
768
|
+
name,
|
|
769
|
+
type,
|
|
770
|
+
className: cn("outline-none text-sm w-96", searchClassName),
|
|
771
|
+
placeholder,
|
|
772
|
+
...props
|
|
773
|
+
}
|
|
774
|
+
)
|
|
775
|
+
]
|
|
776
|
+
}
|
|
777
|
+
);
|
|
778
|
+
}
|
|
779
|
+
|
|
664
780
|
// src/components/modal/Modal.tsx
|
|
665
781
|
var import_framer_motion = require("framer-motion");
|
|
666
|
-
var
|
|
782
|
+
var import_react3 = require("react");
|
|
667
783
|
var import_react_dom = require("react-dom");
|
|
668
784
|
var import_fa = require("react-icons/fa");
|
|
669
785
|
var import_io5 = require("react-icons/io5");
|
|
670
786
|
|
|
671
787
|
// src/components/Loader/Loader.tsx
|
|
672
|
-
var
|
|
788
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
673
789
|
var Loader = ({ className, color = "#F54C00", size = "50px", speed = "1s" }) => {
|
|
674
|
-
return /* @__PURE__ */ (0,
|
|
790
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: `loader`, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
675
791
|
"div",
|
|
676
792
|
{
|
|
677
793
|
className: `spinner ${className}`,
|
|
@@ -688,7 +804,7 @@ var Loader = ({ className, color = "#F54C00", size = "50px", speed = "1s" }) =>
|
|
|
688
804
|
};
|
|
689
805
|
|
|
690
806
|
// src/components/modal/Modal.tsx
|
|
691
|
-
var
|
|
807
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
692
808
|
function Modal({
|
|
693
809
|
isOpen,
|
|
694
810
|
onClose,
|
|
@@ -708,13 +824,13 @@ function Modal({
|
|
|
708
824
|
customLoader = null,
|
|
709
825
|
footerClassName
|
|
710
826
|
}) {
|
|
711
|
-
const modalRef = (0,
|
|
827
|
+
const modalRef = (0, import_react3.useRef)(null);
|
|
712
828
|
const handleBackdropClick = (e) => {
|
|
713
829
|
if (e.target === e.currentTarget && closeOnBackdropClick) {
|
|
714
830
|
onClose();
|
|
715
831
|
}
|
|
716
832
|
};
|
|
717
|
-
(0,
|
|
833
|
+
(0, import_react3.useEffect)(() => {
|
|
718
834
|
const handleEscape = (e) => {
|
|
719
835
|
if (e.key === "Escape" && isOpen && closeOnEscape) {
|
|
720
836
|
onClose();
|
|
@@ -729,7 +845,7 @@ function Modal({
|
|
|
729
845
|
document.body.style.overflow = "unset";
|
|
730
846
|
};
|
|
731
847
|
}, [isOpen, onClose, closeOnEscape]);
|
|
732
|
-
const modalContent = /* @__PURE__ */ (0,
|
|
848
|
+
const modalContent = /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_framer_motion.AnimatePresence, { children: isOpen && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
733
849
|
"div",
|
|
734
850
|
{
|
|
735
851
|
className: "fixed inset-0 bg-gray-500 bg-opacity-50 flex justify-center items-center z-1000 p-4",
|
|
@@ -748,7 +864,7 @@ function Modal({
|
|
|
748
864
|
zIndex
|
|
749
865
|
},
|
|
750
866
|
children: [
|
|
751
|
-
/* @__PURE__ */ (0,
|
|
867
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
752
868
|
import_framer_motion.motion.div,
|
|
753
869
|
{
|
|
754
870
|
ref: modalRef,
|
|
@@ -769,7 +885,7 @@ function Modal({
|
|
|
769
885
|
// Ensure modal doesn't exceed viewport height
|
|
770
886
|
},
|
|
771
887
|
children: [
|
|
772
|
-
/* @__PURE__ */ (0,
|
|
888
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
773
889
|
"div",
|
|
774
890
|
{
|
|
775
891
|
style: {
|
|
@@ -777,43 +893,43 @@ function Modal({
|
|
|
777
893
|
},
|
|
778
894
|
className: "sticky top-0 z-10 flex justify-between items-center bg-white text-2xl p-8 pb-4 rounded-t-3xl",
|
|
779
895
|
children: [
|
|
780
|
-
/* @__PURE__ */ (0,
|
|
781
|
-
/* @__PURE__ */ (0,
|
|
782
|
-
onPrint && /* @__PURE__ */ (0,
|
|
896
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h2", { className: "font-semibold", children: title }),
|
|
897
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center space-x-4", children: [
|
|
898
|
+
onPrint && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
783
899
|
"button",
|
|
784
900
|
{
|
|
785
901
|
onClick: onPrint,
|
|
786
902
|
className: "flex items-center gap-1 hover:text-gray-300 text-sm border p-1 rounded",
|
|
787
903
|
children: [
|
|
788
|
-
/* @__PURE__ */ (0,
|
|
789
|
-
/* @__PURE__ */ (0,
|
|
904
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_fa.FaPrint, { name: "FaPrint" }),
|
|
905
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "Print" })
|
|
790
906
|
]
|
|
791
907
|
}
|
|
792
908
|
),
|
|
793
|
-
onExport && /* @__PURE__ */ (0,
|
|
909
|
+
onExport && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
794
910
|
"button",
|
|
795
911
|
{
|
|
796
912
|
onClick: onExport,
|
|
797
913
|
className: "flex items-center gap-1 hover:text-gray-300 text-sm border p-1 rounded",
|
|
798
914
|
children: [
|
|
799
|
-
/* @__PURE__ */ (0,
|
|
800
|
-
/* @__PURE__ */ (0,
|
|
915
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_fa.FaFileExport, {}),
|
|
916
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "Export" })
|
|
801
917
|
]
|
|
802
918
|
}
|
|
803
919
|
),
|
|
804
|
-
/* @__PURE__ */ (0,
|
|
920
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
805
921
|
"button",
|
|
806
922
|
{
|
|
807
923
|
onClick: onClose,
|
|
808
924
|
className: "px-2 hover:opacity-70 transition-opacity",
|
|
809
|
-
children: /* @__PURE__ */ (0,
|
|
925
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_io5.IoCloseCircleOutline, { color: "#8898AA", size: 25 })
|
|
810
926
|
}
|
|
811
927
|
)
|
|
812
928
|
] })
|
|
813
929
|
]
|
|
814
930
|
}
|
|
815
931
|
),
|
|
816
|
-
/* @__PURE__ */ (0,
|
|
932
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
817
933
|
"div",
|
|
818
934
|
{
|
|
819
935
|
className: cn(
|
|
@@ -823,7 +939,7 @@ function Modal({
|
|
|
823
939
|
children
|
|
824
940
|
}
|
|
825
941
|
),
|
|
826
|
-
footer && /* @__PURE__ */ (0,
|
|
942
|
+
footer && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
827
943
|
"div",
|
|
828
944
|
{
|
|
829
945
|
className: cn("sticky bottom-0 flex justify-end p-4 space-x-4 border-t bg-white ", footerClassName),
|
|
@@ -837,7 +953,7 @@ function Modal({
|
|
|
837
953
|
]
|
|
838
954
|
}
|
|
839
955
|
),
|
|
840
|
-
isLoading && /* @__PURE__ */ (0,
|
|
956
|
+
isLoading && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
841
957
|
"div",
|
|
842
958
|
{
|
|
843
959
|
className: "fixed inset-0 flex items-center justify-center bg-gray-200/60",
|
|
@@ -846,7 +962,7 @@ function Modal({
|
|
|
846
962
|
"aria-live": "polite",
|
|
847
963
|
role: "status",
|
|
848
964
|
onClick: (e) => e.stopPropagation(),
|
|
849
|
-
children: customLoader ? customLoader : /* @__PURE__ */ (0,
|
|
965
|
+
children: customLoader ? customLoader : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Loader, { size: "48px" })
|
|
850
966
|
}
|
|
851
967
|
)
|
|
852
968
|
]
|
|
@@ -868,6 +984,7 @@ function Modal({
|
|
|
868
984
|
Modal,
|
|
869
985
|
ResetColumnsButton,
|
|
870
986
|
ResetFiltersButton,
|
|
987
|
+
SearchInput,
|
|
871
988
|
TableLayoutToolbarControls
|
|
872
989
|
});
|
|
873
990
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/index.ts","../../src/components/tabs/EztrakTabs.tsx","../../src/utils/cn.ts","../../src/components/pagination/CustomPagination.tsx","../../src/utils/handleApiError.ts","../../src/components/search-filters/ResetFiltersButton.tsx","../../src/components/modal/Modal.tsx","../../src/components/Loader/Loader.tsx"],"sourcesContent":["export { EztrakTabs } from \"./tabs/EztrakTabs\";\r\nexport type {\r\n EztrakTab,\r\n EztrakTabsClassNames,\r\n EztrakTabsProps,\r\n} from \"./tabs/types\";\r\nexport {\r\n CustomPagination,\r\n ResetColumnsButton,\r\n TableLayoutToolbarControls,\r\n} from \"./pagination/CustomPagination\";\r\nexport type {\r\n CustomPaginationClassNames,\r\n CustomPaginationProps,\r\n LayoutStatus,\r\n PaginationData,\r\n ResetColumnsButtonProps,\r\n TableLayoutToolbarControlsProps,\r\n} from \"./pagination/types\";\r\nexport { ResetFiltersButton } from \"./search-filters/ResetFiltersButton\";\r\nexport type { ResetFiltersButtonProps } from \"./search-filters/types\";\r\nexport { Modal } from \"./modal/Modal\";\r\nexport type { ModalProps } from \"./modal/types\";\r\nexport { Loader } from \"./Loader\";\r\nexport type { LoaderProps } from \"./Loader/Loader.types\";\r\n","import {\r\n useCallback,\r\n useEffect,\r\n useId,\r\n useRef,\r\n useState,\r\n type KeyboardEvent,\r\n} from \"react\";\r\nimport { cn } from \"../../utils/cn\";\r\nimport type { EztrakTab, EztrakTabsProps } from \"./types\";\r\n\r\nfunction getInitialTabId(\r\n tabs: EztrakTab[],\r\n defaultTabId?: string\r\n): string | undefined {\r\n if (defaultTabId && tabs.some((t) => t.id === defaultTabId && !t.disabled)) {\r\n return defaultTabId;\r\n }\r\n return tabs.find((t) => !t.disabled)?.id;\r\n}\r\n\r\nfunction getEnabledTabIds(tabs: EztrakTab[]): string[] {\r\n return tabs.filter((t) => !t.disabled).map((t) => t.id);\r\n}\r\n\r\nexport function EztrakTabs({\r\n tabs,\r\n activeTab,\r\n defaultTabId,\r\n onTabChange,\r\n showPanels = true,\r\n keepMounted = false,\r\n classNames,\r\n className,\r\n}: EztrakTabsProps) {\r\n const baseId = useId().replace(/:/g, \"\");\r\n const isControlled = activeTab !== undefined && activeTab !== null;\r\n const [uncontrolledActive, setUncontrolledActive] = useState(() =>\r\n getInitialTabId(tabs, defaultTabId)\r\n );\r\n const tabRefs = useRef<Map<string, HTMLButtonElement>>(new Map());\r\n\r\n const displayActive = isControlled ? activeTab : uncontrolledActive;\r\n\r\n useEffect(() => {\r\n if (isControlled) return;\r\n const enabledIds = getEnabledTabIds(tabs);\r\n if (!displayActive || !enabledIds.includes(displayActive)) {\r\n const next = getInitialTabId(tabs, defaultTabId);\r\n if (next !== displayActive) {\r\n setUncontrolledActive(next);\r\n }\r\n }\r\n }, [tabs, defaultTabId, isControlled, displayActive]);\r\n\r\n const handleTabClick = useCallback(\r\n (tabId: string, disabled?: boolean) => {\r\n if (disabled) return;\r\n if (!isControlled) {\r\n setUncontrolledActive(tabId);\r\n }\r\n onTabChange?.(tabId);\r\n },\r\n [isControlled, onTabChange]\r\n );\r\n\r\n const focusTab = useCallback((tabId: string) => {\r\n tabRefs.current.get(tabId)?.focus();\r\n }, []);\r\n\r\n const handleListKeyDown = useCallback(\r\n (event: KeyboardEvent<HTMLUListElement>) => {\r\n const enabledIds = getEnabledTabIds(tabs);\r\n if (enabledIds.length === 0) return;\r\n\r\n const currentIndex = displayActive\r\n ? enabledIds.indexOf(displayActive)\r\n : -1;\r\n let nextIndex = currentIndex;\r\n\r\n switch (event.key) {\r\n case \"ArrowRight\":\r\n case \"ArrowDown\":\r\n event.preventDefault();\r\n nextIndex =\r\n currentIndex < 0\r\n ? 0\r\n : (currentIndex + 1) % enabledIds.length;\r\n break;\r\n case \"ArrowLeft\":\r\n case \"ArrowUp\":\r\n event.preventDefault();\r\n nextIndex =\r\n currentIndex < 0\r\n ? enabledIds.length - 1\r\n : (currentIndex - 1 + enabledIds.length) % enabledIds.length;\r\n break;\r\n case \"Home\":\r\n event.preventDefault();\r\n nextIndex = 0;\r\n break;\r\n case \"End\":\r\n event.preventDefault();\r\n nextIndex = enabledIds.length - 1;\r\n break;\r\n default:\r\n return;\r\n }\r\n\r\n const nextId = enabledIds[nextIndex];\r\n if (nextId) {\r\n handleTabClick(nextId);\r\n focusTab(nextId);\r\n }\r\n },\r\n [tabs, displayActive, handleTabClick, focusTab]\r\n );\r\n\r\n if (!tabs.length) {\r\n return null;\r\n }\r\n\r\n const wrapperClass = cn(\r\n \"eztrak-tabs-wrapper\",\r\n classNames?.wrapper,\r\n className\r\n );\r\n\r\n return (\r\n <div className={wrapperClass}>\r\n <div className={cn(\"eztrak-tabs-container\", classNames?.container)}>\r\n <nav\r\n className={cn(\"eztrak-tabs-nav\", classNames?.nav)}\r\n aria-label=\"Tabs\"\r\n >\r\n <ul\r\n role=\"tablist\"\r\n className={cn(\"eztrak-tabs-list\", classNames?.list)}\r\n onKeyDown={handleListKeyDown}\r\n >\r\n {tabs.map((tab) => {\r\n const isActive = displayActive === tab.id;\r\n const tabId = `${baseId}-tab-${tab.id}`;\r\n const panelId = `${baseId}-panel-${tab.id}`;\r\n\r\n return (\r\n <li\r\n key={tab.id}\r\n role=\"presentation\"\r\n className={cn(\r\n \"eztrak-tabs-item\",\r\n isActive && \"eztrak-tabs-item-active\",\r\n classNames?.item,\r\n isActive && classNames?.itemActive\r\n )}\r\n >\r\n <button\r\n ref={(el) => {\r\n if (el) {\r\n tabRefs.current.set(tab.id, el);\r\n } else {\r\n tabRefs.current.delete(tab.id);\r\n }\r\n }}\r\n type=\"button\"\r\n role=\"tab\"\r\n id={tabId}\r\n aria-selected={isActive}\r\n aria-controls={showPanels ? panelId : undefined}\r\n tabIndex={isActive ? 0 : -1}\r\n disabled={tab.disabled}\r\n className={cn(\r\n \"eztrak-tabs-button\",\r\n isActive && \"eztrak-tabs-button-active\",\r\n classNames?.button,\r\n isActive && classNames?.buttonActive\r\n )}\r\n onClick={() => handleTabClick(tab.id, tab.disabled)}\r\n >\r\n {tab.icon ? (\r\n <span\r\n className={cn(\"eztrak-tabs-icon\", classNames?.icon)}\r\n aria-hidden\r\n >\r\n {tab.icon}\r\n </span>\r\n ) : null}\r\n <span\r\n className={cn(\"eztrak-tabs-label\", classNames?.label)}\r\n >\r\n {tab.label}\r\n </span>\r\n {isActive ? (\r\n <span\r\n className={cn(\r\n \"eztrak-tabs-underline\",\r\n classNames?.underline\r\n )}\r\n aria-hidden\r\n />\r\n ) : null}\r\n </button>\r\n </li>\r\n );\r\n })}\r\n </ul>\r\n </nav>\r\n\r\n {showPanels ? (\r\n <div className={cn(\"eztrak-tabs-content\", classNames?.content)}>\r\n {tabs.map((tab) => {\r\n const isActive = displayActive === tab.id;\r\n const panelId = `${baseId}-panel-${tab.id}`;\r\n const tabId = `${baseId}-tab-${tab.id}`;\r\n\r\n if (!keepMounted && !isActive) {\r\n return null;\r\n }\r\n\r\n return (\r\n <div\r\n key={tab.id}\r\n id={panelId}\r\n role=\"tabpanel\"\r\n aria-labelledby={tabId}\r\n hidden={!isActive}\r\n className={cn(\"eztrak-tabs-panel\", classNames?.panel)}\r\n >\r\n {tab.content}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n ) : null}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import clsx from \"clsx\";\r\nimport { twMerge } from \"tailwind-merge\";\r\n\r\nexport function cn(...inputs: Parameters<typeof clsx>) {\r\n return twMerge(clsx(inputs));\r\n}\r\n","import { type ChangeEvent, type ReactNode } from \"react\";\r\nimport { useSearchParams } from \"react-router-dom\";\r\nimport { cn } from \"../../utils/cn\";\r\nimport { confirmationAlert } from \"../../utils/handleApiError\";\r\nimport type {\r\n CustomPaginationProps,\r\n ResetColumnsButtonProps,\r\n TableLayoutToolbarControlsProps,\r\n} from \"./types\";\r\n\r\nconst DEFAULT_PAGE_SIZE_OPTIONS = [10, 20, 30, 50, 100];\r\nconst ALL_PAGES_VALUE = -1;\r\n\r\nfunction padCount(num: number) {\r\n return num.toString().padStart(2, \"0\");\r\n}\r\n\r\nfunction RefreshIcon({\r\n size = 14,\r\n className,\r\n}: {\r\n size?: number;\r\n className?: string;\r\n}) {\r\n return (\r\n <svg\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n aria-hidden=\"true\"\r\n className={className}\r\n >\r\n <path d=\"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8\" />\r\n <path d=\"M21 3v5h-5\" />\r\n <path d=\"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16\" />\r\n <path d=\"M8 16H3v5\" />\r\n </svg>\r\n );\r\n}\r\n\r\nexport function ResetColumnsButton({\r\n onReset,\r\n disabled = false,\r\n isLoading = false,\r\n}: ResetColumnsButtonProps) {\r\n const handleClick = () => {\r\n confirmationAlert(onReset, {\r\n text: \"Reset column order, widths, and visibility to defaults?\",\r\n icon: \"warning\",\r\n title: \"Reset column layout to default\",\r\n });\r\n };\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={handleClick}\r\n disabled={disabled || isLoading}\r\n title=\"Reset column layout to default\"\r\n 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\"\r\n >\r\n <RefreshIcon size={14} className={cn(isLoading ? \"animate-spin\" : \"\")} />\r\n Reset columns\r\n </button>\r\n );\r\n}\r\n\r\nexport function TableLayoutToolbarControls({\r\n layoutStatus = {},\r\n onResetLayout,\r\n renderResetControl,\r\n isLoading = false,\r\n}: TableLayoutToolbarControlsProps) {\r\n const { isLayoutLoading, isLayoutSaving, isLayoutResetting } = layoutStatus;\r\n const isLayoutBusy = isLayoutLoading || isLayoutSaving || isLayoutResetting;\r\n\r\n return (\r\n <div className=\"flex items-center gap-3\">\r\n {onResetLayout &&\r\n (renderResetControl ? (\r\n renderResetControl(onResetLayout)\r\n ) : (\r\n <ResetColumnsButton\r\n onReset={onResetLayout}\r\n disabled={isLayoutBusy}\r\n isLoading={isLoading}\r\n />\r\n ))}\r\n </div>\r\n );\r\n}\r\n\r\nexport function CustomPagination({\r\n paginationData,\r\n paginationPageSize,\r\n pageSizeOptions: pageSizeOptionsProp,\r\n isLoading = false,\r\n paramNames,\r\n onPageChange,\r\n onPageSizeChange,\r\n onResetLayout,\r\n renderResetControl,\r\n layoutStatus,\r\n showAllPagesOption = false,\r\n classNames,\r\n className,\r\n}: CustomPaginationProps) {\r\n const [searchParams, setSearchParams] = useSearchParams();\r\n const pageKey = paramNames?.page ?? \"page\";\r\n const perPageKey = paramNames?.perPage ?? \"perPage\";\r\n const pageSizeOptions =\r\n pageSizeOptionsProp ?? paginationPageSize ?? DEFAULT_PAGE_SIZE_OPTIONS;\r\n const perPageParam = searchParams.get(perPageKey);\r\n const perPageNumber =\r\n perPageParam !== null && perPageParam !== \"\"\r\n ? parseInt(perPageParam, 10)\r\n : NaN;\r\n const isShowingAll = perPageNumber === ALL_PAGES_VALUE;\r\n\r\n const currentPage = paginationData\r\n ? Math.max(0, paginationData.currentPage - 1)\r\n : 0;\r\n\r\n const handlePageChange = (pageNumber: number) => {\r\n if (\r\n !paginationData ||\r\n pageNumber < 0 ||\r\n pageNumber >= paginationData.pageCount\r\n ) {\r\n return;\r\n }\r\n\r\n const safePage = Math.max(\r\n 1,\r\n Math.min(pageNumber + 1, paginationData.pageCount)\r\n );\r\n const newParams = new URLSearchParams(searchParams);\r\n newParams.set(pageKey, String(safePage));\r\n setSearchParams(newParams, { replace: true });\r\n onPageChange?.(safePage);\r\n };\r\n\r\n const handlePageSizeChange = (event: ChangeEvent<HTMLSelectElement>) => {\r\n const parsed = parseInt(event.target.value, 10);\r\n if (\r\n !Number.isFinite(parsed) ||\r\n (parsed < 1 && parsed !== ALL_PAGES_VALUE)\r\n ) {\r\n return;\r\n }\r\n\r\n const newParams = new URLSearchParams(searchParams);\r\n newParams.set(pageKey, \"1\");\r\n newParams.set(perPageKey, String(parsed));\r\n setSearchParams(newParams, { replace: true });\r\n onPageSizeChange?.(parsed);\r\n };\r\n\r\n const createPageButtons = () => {\r\n const buttons: ReactNode[] = [];\r\n const maxButtons = 5;\r\n const totalPages = Math.max(1, paginationData?.pageCount ?? 1);\r\n\r\n let startPage = Math.max(0, currentPage - Math.floor(maxButtons / 2));\r\n let endPage = Math.min(totalPages - 1, startPage + maxButtons - 1);\r\n\r\n if (endPage - startPage + 1 < maxButtons) {\r\n startPage = Math.max(0, endPage - maxButtons + 1);\r\n }\r\n\r\n if (startPage > 0) {\r\n buttons.push(\r\n <button\r\n key=\"1\"\r\n type=\"button\"\r\n onClick={() => handlePageChange(0)}\r\n aria-label=\"Page 1\"\r\n className={cn(\r\n \"px-3 py-2 text-sm text-gray-600 hover:text-blue-600 hover:bg-blue-50 rounded-md transition-colors\",\r\n classNames?.pageButton\r\n )}\r\n >\r\n 1\r\n </button>\r\n );\r\n\r\n if (startPage > 1) {\r\n buttons.push(\r\n <span\r\n key=\"ellipsis1\"\r\n aria-hidden=\"true\"\r\n className=\"px-2 py-2 text-gray-400\"\r\n >\r\n ...\r\n </span>\r\n );\r\n }\r\n }\r\n\r\n for (let i = startPage; i <= endPage; i++) {\r\n const isActive = currentPage === i;\r\n buttons.push(\r\n <button\r\n key={i + 1}\r\n type=\"button\"\r\n onClick={() => handlePageChange(i)}\r\n aria-label={`Page ${i + 1}`}\r\n aria-current={isActive ? \"page\" : undefined}\r\n className={cn(\r\n \"px-3 py-2 text-sm rounded-md transition-colors\",\r\n isActive\r\n ? cn(\"bg-gray-400 text-white\", classNames?.activePageButton)\r\n : cn(\r\n \"text-gray-600 hover:text-gray-600 hover:bg-gray-50\",\r\n classNames?.pageButton\r\n )\r\n )}\r\n >\r\n {i + 1}\r\n </button>\r\n );\r\n }\r\n\r\n if (endPage < totalPages - 1) {\r\n if (endPage < totalPages - 2) {\r\n buttons.push(\r\n <span\r\n key=\"ellipsis2\"\r\n aria-hidden=\"true\"\r\n className=\"px-2 py-2 text-gray-400\"\r\n >\r\n ...\r\n </span>\r\n );\r\n }\r\n\r\n buttons.push(\r\n <button\r\n key={totalPages}\r\n type=\"button\"\r\n onClick={() => handlePageChange(totalPages - 1)}\r\n aria-label={`Page ${totalPages}`}\r\n className={cn(\r\n \"px-3 py-2 text-sm text-gray-600 hover:text-gray-600 hover:bg-gray-50 rounded-md transition-colors\",\r\n classNames?.pageButton\r\n )}\r\n >\r\n {totalPages}\r\n </button>\r\n );\r\n }\r\n\r\n return buttons;\r\n };\r\n\r\n if (isLoading || !paginationData) {\r\n return (\r\n <div className=\"flex items-center justify-center p-6 bg-gray-50\">\r\n <span className=\"text-gray-500\">\r\n {isLoading ? \"Loading...\" : \"No pagination data\"}\r\n </span>\r\n </div>\r\n );\r\n }\r\n\r\n const effectiveSizeOptions =\r\n paginationData.perPage > 0 &&\r\n !pageSizeOptions.includes(paginationData.perPage)\r\n ? [...pageSizeOptions, paginationData.perPage].sort((a, b) => a - b)\r\n : pageSizeOptions;\r\n\r\n const selectValue = isShowingAll\r\n ? ALL_PAGES_VALUE\r\n : paginationData.perPage ||\r\n (Number.isFinite(perPageNumber) && perPageNumber > 0\r\n ? perPageNumber\r\n : 10);\r\n\r\n const startItem =\r\n paginationData.totalCount === 0\r\n ? 0\r\n : (paginationData.currentPage - 1) * paginationData.perPage + 1;\r\n const endItem = Math.min(\r\n startItem + paginationData.perPage - 1,\r\n paginationData.totalCount\r\n );\r\n\r\n const { isLayoutLoading, isLayoutSaving, isLayoutResetting } =\r\n layoutStatus ?? {};\r\n const isLayoutBusy =\r\n isLayoutLoading || isLayoutSaving || isLayoutResetting;\r\n\r\n return (\r\n <div\r\n className={cn(\r\n \"flex items-center justify-between pb-4\",\r\n className,\r\n classNames?.root\r\n )}\r\n >\r\n <div className={cn(\"flex-1\", classNames?.info)}>\r\n <span className=\"text-xs font-medium text-neutral-400\">\r\n {isShowingAll\r\n ? `Showing All ${paginationData.totalCount ?? 0} Results`\r\n : `Showing ${padCount(startItem)} - ${padCount(endItem)} of ${paginationData.totalCount ?? 0} results`}\r\n </span>\r\n </div>\r\n\r\n <nav\r\n aria-label=\"Pagination\"\r\n className={cn(\"flex items-center space-x-1\", classNames?.nav)}\r\n >\r\n <button\r\n type=\"button\"\r\n onClick={() => handlePageChange(currentPage - 1)}\r\n disabled={currentPage === 0 || isShowingAll}\r\n className=\"p-2 text-gray-400 hover:text-gray-600 disabled:opacity-30 disabled:cursor-not-allowed transition-colors\"\r\n aria-label=\"Previous page\"\r\n >\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\r\n <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\" />\r\n </svg>\r\n </button>\r\n\r\n <div className=\"flex items-center space-x-1\">\r\n {isShowingAll ? (\r\n <span className=\"px-3 py-2 text-sm text-gray-400\" aria-hidden=\"true\">\r\n All\r\n </span>\r\n ) : (\r\n createPageButtons()\r\n )}\r\n </div>\r\n\r\n <button\r\n type=\"button\"\r\n onClick={() => handlePageChange(currentPage + 1)}\r\n disabled={\r\n currentPage >= paginationData.pageCount - 1 || isShowingAll\r\n }\r\n className=\"p-2 text-gray-400 hover:text-gray-600 disabled:opacity-30 disabled:cursor-not-allowed transition-colors\"\r\n aria-label=\"Next page\"\r\n >\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\r\n <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\" />\r\n </svg>\r\n </button>\r\n </nav>\r\n\r\n <div className=\"flex-1 flex justify-end\">\r\n <div className=\"flex items-center gap-3\">\r\n {onResetLayout &&\r\n (renderResetControl ? (\r\n renderResetControl(onResetLayout)\r\n ) : (\r\n <ResetColumnsButton\r\n onReset={onResetLayout}\r\n disabled={isLayoutBusy}\r\n isLoading={isLoading}\r\n />\r\n ))}\r\n <div className=\"flex items-center space-x-2\">\r\n <label\r\n htmlFor=\"pagination-per-page\"\r\n className=\"text-sm text-gray-600\"\r\n >\r\n Items per page\r\n </label>\r\n <select\r\n id=\"pagination-per-page\"\r\n value={selectValue}\r\n onChange={handlePageSizeChange}\r\n className={cn(\r\n \"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\",\r\n classNames?.select\r\n )}\r\n >\r\n {showAllPagesOption && (\r\n <option value={ALL_PAGES_VALUE}>All</option>\r\n )}\r\n {effectiveSizeOptions.map((option) => (\r\n <option key={option} value={option}>\r\n {option}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nexport default CustomPagination;\r\n","import toast from \"react-hot-toast\";\r\nimport Swal from \"sweetalert2\";\r\n\r\nexport type RtkQueryError = {\r\n status?: number | string;\r\n originalStatus?: number;\r\n data?: {\r\n errors?: Record<string, string[]>;\r\n message?: string;\r\n title?: string;\r\n };\r\n error?: string;\r\n};\r\n\r\nexport interface HandleApiErrorOptions {\r\n showAlert?: boolean;\r\n fallbackMessage?: string;\r\n}\r\n\r\nexport function formatValidationErrorsHtml(\r\n errors: Record<string, string[]>\r\n): string {\r\n const items = Object.keys(errors).flatMap((field) =>\r\n (errors[field] || []).map((msg) => `<li>${msg}</li>`)\r\n );\r\n return `\r\n <div style=\"text-align:left\">\r\n <p>Please review and correct the following:</p>\r\n <ul style=\"margin:8px 0 0 16px; list-style:disc;\">\r\n ${items.join(\"\")}\r\n </ul>\r\n </div>\r\n `;\r\n}\r\n\r\nfunction showValidationAlert(html: string): void {\r\n void Swal.fire({\r\n title: \"Validation errors\",\r\n html,\r\n icon: \"error\",\r\n confirmButtonText: \"OK\",\r\n showCancelButton: false,\r\n confirmButtonColor: \"#FF7335\",\r\n });\r\n}\r\n\r\n/** Handles RTK Query errors with built-in toast.error or SweetAlert (when showAlert is true). */\r\nexport function handleApiError(\r\n error: RtkQueryError | null | undefined,\r\n { showAlert = false, fallbackMessage }: HandleApiErrorOptions = {}\r\n): void {\r\n if (!error) return;\r\n\r\n const status = error.status ?? error.originalStatus;\r\n const data = error.data;\r\n\r\n if (status === 200) {\r\n return;\r\n }\r\n\r\n if (data?.errors && typeof data.errors === \"object\") {\r\n const errors = data.errors;\r\n\r\n if (showAlert) {\r\n showValidationAlert(formatValidationErrorsHtml(errors));\r\n } else {\r\n Object.keys(errors).forEach((field) => {\r\n (errors[field] || []).forEach((errorMessage) => {\r\n toast.error(errorMessage);\r\n });\r\n });\r\n }\r\n return;\r\n }\r\n\r\n if (status === 404) {\r\n return;\r\n }\r\n\r\n const message =\r\n fallbackMessage ||\r\n data?.message ||\r\n data?.title ||\r\n error.error ||\r\n \"An error occurred. Please try again.\";\r\n\r\n toast.error(message);\r\n}\r\n\r\nexport interface ConfirmationAlertOptions {\r\n title?: string;\r\n text?: string;\r\n icon?: \"warning\" | \"info\" | \"question\" | \"error\" | \"success\";\r\n confirmButtonText?: string;\r\n cancelButtonText?: string;\r\n}\r\n\r\nexport function confirmationAlert(\r\n onConfirm: () => void,\r\n options: ConfirmationAlertOptions = {}\r\n): void {\r\n void Swal.fire({\r\n title: options.title ?? \"Are you sure?\",\r\n text: options.text,\r\n icon: options.icon ?? \"warning\",\r\n showCancelButton: true,\r\n confirmButtonText: options.confirmButtonText ?? \"Yes\",\r\n cancelButtonText: options.cancelButtonText ?? \"Cancel\",\r\n confirmButtonColor: \"#FF7335\",\r\n }).then((result) => {\r\n if (result.isConfirmed) {\r\n onConfirm();\r\n }\r\n });\r\n}\r\n","import { useSearchParams } from \"react-router-dom\";\r\nimport { cn } from \"../../utils/cn\";\r\nimport type {\r\n ResetFiltersButtonProps,\r\n ResetFiltersButtonVariant,\r\n} from \"./types\";\r\n\r\nconst BASE_STYLES =\r\n \"inline-flex items-center gap-1.5 px-5 py-3 rounded-md text-sm font-medium transition-colors duration-200 focus:outline-none disabled:cursor-not-allowed disabled:opacity-50\";\r\n\r\nconst VARIANTS: Record<ResetFiltersButtonVariant, string> = {\r\n primary:\r\n \"bg-white text-secondary border border-secondary hover:bg-lightGray hover:text-black\",\r\n \"primary-outline\":\r\n \"bg-white text-primary-150 border border-primary-150 font-bold hover:bg-primary-100 hover:text-white\",\r\n \"primary-fill\":\r\n \"bg-primary-150 text-white border border-primary-150 hover:bg-primary/90\",\r\n secondary:\r\n \"bg-primary-150 text-white border border-primary-150 hover:bg-primary/90\",\r\n danger: \"bg-red-600 text-white border border-red-600 hover:bg-red-700\",\r\n outline: \"bg-white text-primary border border-primary hover:bg-primary/10\",\r\n ghost:\r\n \"bg-transparent text-secondary border border-transparent hover:bg-primary/10\",\r\n};\r\n\r\nfunction ResetIcon({\r\n size = 16,\r\n className,\r\n}: {\r\n size?: number;\r\n className?: string;\r\n}) {\r\n return (\r\n <svg\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n aria-hidden=\"true\"\r\n className={className}\r\n >\r\n <path d=\"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8\" />\r\n <path d=\"M21 3v5h-5\" />\r\n <path d=\"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16\" />\r\n <path d=\"M8 16H3v5\" />\r\n </svg>\r\n );\r\n}\r\n\r\nexport function ResetFiltersButton({\r\n label = \"Reset Filters\",\r\n showLabel = true,\r\n icon,\r\n variant = \"primary-outline\",\r\n className,\r\n onReset,\r\n disabled = false,\r\n}: ResetFiltersButtonProps) {\r\n const [, setSearchParams] = useSearchParams();\r\n\r\n const handleReset = () => {\r\n setSearchParams({}, { replace: true });\r\n onReset?.();\r\n };\r\n\r\n const resolvedIcon = icon === undefined ? <ResetIcon size={16} /> : icon;\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={handleReset}\r\n disabled={disabled}\r\n className={cn(BASE_STYLES, VARIANTS[variant], className)}\r\n >\r\n {resolvedIcon}\r\n {showLabel && label}\r\n </button>\r\n );\r\n}\r\n","import { AnimatePresence, motion } from \"framer-motion\";\r\nimport { useEffect, useRef, type MouseEvent } from \"react\";\r\nimport { createPortal } from \"react-dom\";\r\nimport { FaFileExport, FaPrint } from \"react-icons/fa\";\r\nimport { IoCloseCircleOutline } from \"react-icons/io5\";\r\nimport { cn } from \"../../utils/cn\";\r\nimport { Loader } from \"../Loader\";\r\nimport type { ModalProps } from \"./types\";\r\n\r\nexport function Modal({\r\n isOpen,\r\n onClose,\r\n title,\r\n children,\r\n footer,\r\n className = \"w-2/3\",\r\n width,\r\n onPrint,\r\n onExport,\r\n modalBodyClassName,\r\n modalBodyWrapperClass,\r\n closeOnBackdropClick = false,\r\n closeOnEscape = true,\r\n zIndex = 1000,\r\n isLoading = false,\r\n customLoader = null,\r\n footerClassName,\r\n}: ModalProps) {\r\n const modalRef = useRef<HTMLDivElement>(null);\r\n\r\n const handleBackdropClick = (e: MouseEvent<HTMLDivElement>) => {\r\n if (e.target === e.currentTarget && closeOnBackdropClick) {\r\n onClose();\r\n }\r\n };\r\n\r\n useEffect(() => {\r\n const handleEscape = (e: KeyboardEvent) => {\r\n if (e.key === \"Escape\" && isOpen && closeOnEscape) {\r\n onClose();\r\n }\r\n };\r\n\r\n if (isOpen) {\r\n document.addEventListener(\"keydown\", handleEscape);\r\n document.body.style.overflow = \"hidden\";\r\n }\r\n\r\n return () => {\r\n document.removeEventListener(\"keydown\", handleEscape);\r\n document.body.style.overflow = \"unset\";\r\n };\r\n }, [isOpen, onClose, closeOnEscape]);\r\n\r\n const modalContent = (\r\n <AnimatePresence>\r\n {isOpen && (\r\n <div\r\n className=\"fixed inset-0 bg-gray-500 bg-opacity-50 flex justify-center items-center z-1000 p-4\"\r\n onClick={handleBackdropClick}\r\n style={{\r\n // Ensure it covers the entire viewport, even in micro frontend context\r\n position: \"fixed\",\r\n top: 0,\r\n left: 0,\r\n right: 0,\r\n bottom: 0,\r\n width: \"100vw\",\r\n height: \"100vh\",\r\n margin: 0,\r\n padding: \"1rem\",\r\n zIndex: zIndex,\r\n }}\r\n >\r\n <motion.div\r\n ref={modalRef}\r\n initial={{ y: \"-100vh\", opacity: 0 }}\r\n animate={{ y: 0, opacity: 1 }}\r\n exit={{ y: \"100vh\", opacity: 0 }}\r\n transition={{ duration: 0.3 }}\r\n className={cn(\r\n `bg-white rounded-3xl shadow-lg max-h-[90vh] flex flex-col mx-auto`,\r\n className,\r\n width,\r\n )}\r\n onClick={(e) => e.stopPropagation()} // Prevent backdrop click when clicking modal content\r\n style={{\r\n maxWidth: \"95vw\", // Ensure modal doesn't exceed viewport width\r\n maxHeight: \"90vh\", // Ensure modal doesn't exceed viewport height\r\n }}\r\n >\r\n {/* Modal Header */}\r\n <div\r\n style={{\r\n borderRadius: \"24px 24px 0 0\",\r\n }}\r\n className=\"sticky top-0 z-10 flex justify-between items-center bg-white text-2xl p-8 pb-4 rounded-t-3xl\"\r\n >\r\n <h2 className=\"font-semibold\">{title}</h2>\r\n <div className=\"flex items-center space-x-4\">\r\n {onPrint && (\r\n <button\r\n onClick={onPrint}\r\n className=\"flex items-center gap-1 hover:text-gray-300 text-sm border p-1 rounded\"\r\n >\r\n <FaPrint name=\"FaPrint\" />\r\n <span>Print</span>\r\n </button>\r\n )}\r\n {onExport && (\r\n <button\r\n onClick={onExport}\r\n className=\"flex items-center gap-1 hover:text-gray-300 text-sm border p-1 rounded\"\r\n >\r\n <FaFileExport />\r\n <span>Export</span>\r\n </button>\r\n )}\r\n <button\r\n onClick={onClose}\r\n className=\"px-2 hover:opacity-70 transition-opacity\"\r\n >\r\n <IoCloseCircleOutline color=\"#8898AA\" size={25} />\r\n </button>\r\n </div>\r\n </div>\r\n <div\r\n className={cn(\r\n \"overflow-y-auto px-8 pb-8 grow scroll scrollbar-hidden\",\r\n modalBodyWrapperClass,\r\n )}\r\n >\r\n {children}\r\n </div>\r\n\r\n {/* Modal Footer */}\r\n {footer && (\r\n\r\n <div\r\n className={cn(\"sticky bottom-0 flex justify-end p-4 space-x-4 border-t bg-white \",footerClassName)}\r\n\r\n style={{\r\n zIndex: 1000,\r\n \r\n borderRadius: \"24px\",\r\n }}\r\n >\r\n {footer}\r\n </div>\r\n )}\r\n </motion.div>\r\n {isLoading && (\r\n <div\r\n className=\"fixed inset-0 flex items-center justify-center bg-gray-200/60\"\r\n style={{ zIndex: 1100 }}\r\n aria-busy=\"true\"\r\n aria-live=\"polite\"\r\n role=\"status\"\r\n onClick={(e) => e.stopPropagation()}\r\n >\r\n {customLoader ? customLoader : <Loader size=\"48px\" />}\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </AnimatePresence>\r\n );\r\n\r\n let modalRoot = document.getElementById(\"modal-root\");\r\n if (!modalRoot) {\r\n modalRoot = document.createElement(\"div\");\r\n modalRoot.id = \"modal-root\";\r\n document.body.appendChild(modalRoot);\r\n }\r\n\r\n return createPortal(modalContent, modalRoot);\r\n}\r\n","import React from 'react';\r\nimport './Loader.css';\r\nimport { LoaderProps } from './Loader.types';\r\n\r\nexport const Loader: React.FC<LoaderProps> = ({ className, color = \"#F54C00\", size = '50px', speed = '1s' }) => {\r\n return (\r\n <div className={`loader`}>\r\n <div \r\n className={`spinner ${className}`} \r\n style={{\r\n border: `4px solid rgba(0, 0, 0, 0.1)`,\r\n borderWidth: '4px',\r\n borderLeftColor: color,\r\n width: size,\r\n height: size,\r\n animation: `spin ${speed} linear infinite`\r\n }}\r\n ></div>\r\n </div>\r\n );\r\n};"],"mappings":"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","names":["clsx","Swal","import_jsx_runtime","import_react_router_dom","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/index.ts","../../src/components/tabs/EztrakTabs.tsx","../../src/utils/cn.ts","../../src/components/pagination/CustomPagination.tsx","../../src/utils/handleApiError.ts","../../src/components/search-filters/ResetFiltersButton.tsx","../../src/components/search-filters/SearchInput.tsx","../../src/components/modal/Modal.tsx","../../src/components/Loader/Loader.tsx"],"sourcesContent":["export { EztrakTabs } from \"./tabs/EztrakTabs\";\r\nexport type {\r\n EztrakTab,\r\n EztrakTabsClassNames,\r\n EztrakTabsProps,\r\n} from \"./tabs/types\";\r\nexport {\r\n CustomPagination,\r\n ResetColumnsButton,\r\n TableLayoutToolbarControls,\r\n} from \"./pagination/CustomPagination\";\r\nexport type {\r\n CustomPaginationClassNames,\r\n CustomPaginationProps,\r\n LayoutStatus,\r\n PaginationData,\r\n ResetColumnsButtonProps,\r\n TableLayoutToolbarControlsProps,\r\n} from \"./pagination/types\";\r\nexport { ResetFiltersButton } from \"./search-filters/ResetFiltersButton\";\r\nexport { SearchInput } from \"./search-filters/SearchInput\";\r\nexport type {\r\n ResetFiltersButtonProps,\r\n ResetFiltersButtonVariant,\r\n SearchInputProps,\r\n} from \"./search-filters/types\";\r\nexport { Modal } from \"./modal/Modal\";\r\nexport type { ModalProps } from \"./modal/types\";\r\nexport { Loader } from \"./Loader\";\r\nexport type { LoaderProps } from \"./Loader/Loader.types\";\r\n","import {\r\n useCallback,\r\n useEffect,\r\n useId,\r\n useRef,\r\n useState,\r\n type KeyboardEvent,\r\n} from \"react\";\r\nimport { cn } from \"../../utils/cn\";\r\nimport type { EztrakTab, EztrakTabsProps } from \"./types\";\r\n\r\nfunction getInitialTabId(\r\n tabs: EztrakTab[],\r\n defaultTabId?: string\r\n): string | undefined {\r\n if (defaultTabId && tabs.some((t) => t.id === defaultTabId && !t.disabled)) {\r\n return defaultTabId;\r\n }\r\n return tabs.find((t) => !t.disabled)?.id;\r\n}\r\n\r\nfunction getEnabledTabIds(tabs: EztrakTab[]): string[] {\r\n return tabs.filter((t) => !t.disabled).map((t) => t.id);\r\n}\r\n\r\nexport function EztrakTabs({\r\n tabs,\r\n activeTab,\r\n defaultTabId,\r\n onTabChange,\r\n showPanels = true,\r\n keepMounted = false,\r\n classNames,\r\n className,\r\n}: EztrakTabsProps) {\r\n const baseId = useId().replace(/:/g, \"\");\r\n const isControlled = activeTab !== undefined && activeTab !== null;\r\n const [uncontrolledActive, setUncontrolledActive] = useState(() =>\r\n getInitialTabId(tabs, defaultTabId)\r\n );\r\n const tabRefs = useRef<Map<string, HTMLButtonElement>>(new Map());\r\n\r\n const displayActive = isControlled ? activeTab : uncontrolledActive;\r\n\r\n useEffect(() => {\r\n if (isControlled) return;\r\n const enabledIds = getEnabledTabIds(tabs);\r\n if (!displayActive || !enabledIds.includes(displayActive)) {\r\n const next = getInitialTabId(tabs, defaultTabId);\r\n if (next !== displayActive) {\r\n setUncontrolledActive(next);\r\n }\r\n }\r\n }, [tabs, defaultTabId, isControlled, displayActive]);\r\n\r\n const handleTabClick = useCallback(\r\n (tabId: string, disabled?: boolean) => {\r\n if (disabled) return;\r\n if (!isControlled) {\r\n setUncontrolledActive(tabId);\r\n }\r\n onTabChange?.(tabId);\r\n },\r\n [isControlled, onTabChange]\r\n );\r\n\r\n const focusTab = useCallback((tabId: string) => {\r\n tabRefs.current.get(tabId)?.focus();\r\n }, []);\r\n\r\n const handleListKeyDown = useCallback(\r\n (event: KeyboardEvent<HTMLUListElement>) => {\r\n const enabledIds = getEnabledTabIds(tabs);\r\n if (enabledIds.length === 0) return;\r\n\r\n const currentIndex = displayActive\r\n ? enabledIds.indexOf(displayActive)\r\n : -1;\r\n let nextIndex = currentIndex;\r\n\r\n switch (event.key) {\r\n case \"ArrowRight\":\r\n case \"ArrowDown\":\r\n event.preventDefault();\r\n nextIndex =\r\n currentIndex < 0\r\n ? 0\r\n : (currentIndex + 1) % enabledIds.length;\r\n break;\r\n case \"ArrowLeft\":\r\n case \"ArrowUp\":\r\n event.preventDefault();\r\n nextIndex =\r\n currentIndex < 0\r\n ? enabledIds.length - 1\r\n : (currentIndex - 1 + enabledIds.length) % enabledIds.length;\r\n break;\r\n case \"Home\":\r\n event.preventDefault();\r\n nextIndex = 0;\r\n break;\r\n case \"End\":\r\n event.preventDefault();\r\n nextIndex = enabledIds.length - 1;\r\n break;\r\n default:\r\n return;\r\n }\r\n\r\n const nextId = enabledIds[nextIndex];\r\n if (nextId) {\r\n handleTabClick(nextId);\r\n focusTab(nextId);\r\n }\r\n },\r\n [tabs, displayActive, handleTabClick, focusTab]\r\n );\r\n\r\n if (!tabs.length) {\r\n return null;\r\n }\r\n\r\n const wrapperClass = cn(\r\n \"eztrak-tabs-wrapper\",\r\n classNames?.wrapper,\r\n className\r\n );\r\n\r\n return (\r\n <div className={wrapperClass}>\r\n <div className={cn(\"eztrak-tabs-container\", classNames?.container)}>\r\n <nav\r\n className={cn(\"eztrak-tabs-nav\", classNames?.nav)}\r\n aria-label=\"Tabs\"\r\n >\r\n <ul\r\n role=\"tablist\"\r\n className={cn(\"eztrak-tabs-list\", classNames?.list)}\r\n onKeyDown={handleListKeyDown}\r\n >\r\n {tabs.map((tab) => {\r\n const isActive = displayActive === tab.id;\r\n const tabId = `${baseId}-tab-${tab.id}`;\r\n const panelId = `${baseId}-panel-${tab.id}`;\r\n\r\n return (\r\n <li\r\n key={tab.id}\r\n role=\"presentation\"\r\n className={cn(\r\n \"eztrak-tabs-item\",\r\n isActive && \"eztrak-tabs-item-active\",\r\n classNames?.item,\r\n isActive && classNames?.itemActive\r\n )}\r\n >\r\n <button\r\n ref={(el) => {\r\n if (el) {\r\n tabRefs.current.set(tab.id, el);\r\n } else {\r\n tabRefs.current.delete(tab.id);\r\n }\r\n }}\r\n type=\"button\"\r\n role=\"tab\"\r\n id={tabId}\r\n aria-selected={isActive}\r\n aria-controls={showPanels ? panelId : undefined}\r\n tabIndex={isActive ? 0 : -1}\r\n disabled={tab.disabled}\r\n className={cn(\r\n \"eztrak-tabs-button\",\r\n isActive && \"eztrak-tabs-button-active\",\r\n classNames?.button,\r\n isActive && classNames?.buttonActive\r\n )}\r\n onClick={() => handleTabClick(tab.id, tab.disabled)}\r\n >\r\n {tab.icon ? (\r\n <span\r\n className={cn(\"eztrak-tabs-icon\", classNames?.icon)}\r\n aria-hidden\r\n >\r\n {tab.icon}\r\n </span>\r\n ) : null}\r\n <span\r\n className={cn(\"eztrak-tabs-label\", classNames?.label)}\r\n >\r\n {tab.label}\r\n </span>\r\n {isActive ? (\r\n <span\r\n className={cn(\r\n \"eztrak-tabs-underline\",\r\n classNames?.underline\r\n )}\r\n aria-hidden\r\n />\r\n ) : null}\r\n </button>\r\n </li>\r\n );\r\n })}\r\n </ul>\r\n </nav>\r\n\r\n {showPanels ? (\r\n <div className={cn(\"eztrak-tabs-content\", classNames?.content)}>\r\n {tabs.map((tab) => {\r\n const isActive = displayActive === tab.id;\r\n const panelId = `${baseId}-panel-${tab.id}`;\r\n const tabId = `${baseId}-tab-${tab.id}`;\r\n\r\n if (!keepMounted && !isActive) {\r\n return null;\r\n }\r\n\r\n return (\r\n <div\r\n key={tab.id}\r\n id={panelId}\r\n role=\"tabpanel\"\r\n aria-labelledby={tabId}\r\n hidden={!isActive}\r\n className={cn(\"eztrak-tabs-panel\", classNames?.panel)}\r\n >\r\n {tab.content}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n ) : null}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import clsx from \"clsx\";\r\nimport { twMerge } from \"tailwind-merge\";\r\n\r\nexport function cn(...inputs: Parameters<typeof clsx>) {\r\n return twMerge(clsx(inputs));\r\n}\r\n","import { type ChangeEvent, type ReactNode } from \"react\";\r\nimport { useSearchParams } from \"react-router-dom\";\r\nimport { cn } from \"../../utils/cn\";\r\nimport { confirmationAlert } from \"../../utils/handleApiError\";\r\nimport type {\r\n CustomPaginationProps,\r\n ResetColumnsButtonProps,\r\n TableLayoutToolbarControlsProps,\r\n} from \"./types\";\r\n\r\nconst DEFAULT_PAGE_SIZE_OPTIONS = [10, 20, 30, 50, 100];\r\nconst ALL_PAGES_VALUE = -1;\r\n\r\nfunction padCount(num: number) {\r\n return num.toString().padStart(2, \"0\");\r\n}\r\n\r\nfunction RefreshIcon({\r\n size = 14,\r\n className,\r\n}: {\r\n size?: number;\r\n className?: string;\r\n}) {\r\n return (\r\n <svg\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n aria-hidden=\"true\"\r\n className={className}\r\n >\r\n <path d=\"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8\" />\r\n <path d=\"M21 3v5h-5\" />\r\n <path d=\"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16\" />\r\n <path d=\"M8 16H3v5\" />\r\n </svg>\r\n );\r\n}\r\n\r\nexport function ResetColumnsButton({\r\n onReset,\r\n disabled = false,\r\n isLoading = false,\r\n}: ResetColumnsButtonProps) {\r\n const handleClick = () => {\r\n confirmationAlert(onReset, {\r\n text: \"Reset column order, widths, and visibility to defaults?\",\r\n icon: \"warning\",\r\n title: \"Reset column layout to default\",\r\n });\r\n };\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={handleClick}\r\n disabled={disabled || isLoading}\r\n title=\"Reset column layout to default\"\r\n 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\"\r\n >\r\n <RefreshIcon size={14} className={cn(isLoading ? \"animate-spin\" : \"\")} />\r\n Reset columns\r\n </button>\r\n );\r\n}\r\n\r\nexport function TableLayoutToolbarControls({\r\n layoutStatus = {},\r\n onResetLayout,\r\n renderResetControl,\r\n isLoading = false,\r\n}: TableLayoutToolbarControlsProps) {\r\n const { isLayoutLoading, isLayoutSaving, isLayoutResetting } = layoutStatus;\r\n const isLayoutBusy = isLayoutLoading || isLayoutSaving || isLayoutResetting;\r\n\r\n return (\r\n <div className=\"flex items-center gap-3\">\r\n {onResetLayout &&\r\n (renderResetControl ? (\r\n renderResetControl(onResetLayout)\r\n ) : (\r\n <ResetColumnsButton\r\n onReset={onResetLayout}\r\n disabled={isLayoutBusy}\r\n isLoading={isLoading}\r\n />\r\n ))}\r\n </div>\r\n );\r\n}\r\n\r\nexport function CustomPagination({\r\n paginationData,\r\n paginationPageSize,\r\n pageSizeOptions: pageSizeOptionsProp,\r\n isLoading = false,\r\n paramNames,\r\n onPageChange,\r\n onPageSizeChange,\r\n onResetLayout,\r\n renderResetControl,\r\n layoutStatus,\r\n showAllPagesOption = false,\r\n classNames,\r\n className,\r\n}: CustomPaginationProps) {\r\n const [searchParams, setSearchParams] = useSearchParams();\r\n const pageKey = paramNames?.page ?? \"page\";\r\n const perPageKey = paramNames?.perPage ?? \"perPage\";\r\n const pageSizeOptions =\r\n pageSizeOptionsProp ?? paginationPageSize ?? DEFAULT_PAGE_SIZE_OPTIONS;\r\n const perPageParam = searchParams.get(perPageKey);\r\n const perPageNumber =\r\n perPageParam !== null && perPageParam !== \"\"\r\n ? parseInt(perPageParam, 10)\r\n : NaN;\r\n const isShowingAll = perPageNumber === ALL_PAGES_VALUE;\r\n\r\n const currentPage = paginationData\r\n ? Math.max(0, paginationData.currentPage - 1)\r\n : 0;\r\n\r\n const handlePageChange = (pageNumber: number) => {\r\n if (\r\n !paginationData ||\r\n pageNumber < 0 ||\r\n pageNumber >= paginationData.pageCount\r\n ) {\r\n return;\r\n }\r\n\r\n const safePage = Math.max(\r\n 1,\r\n Math.min(pageNumber + 1, paginationData.pageCount)\r\n );\r\n const newParams = new URLSearchParams(searchParams);\r\n newParams.set(pageKey, String(safePage));\r\n setSearchParams(newParams, { replace: true });\r\n onPageChange?.(safePage);\r\n };\r\n\r\n const handlePageSizeChange = (event: ChangeEvent<HTMLSelectElement>) => {\r\n const parsed = parseInt(event.target.value, 10);\r\n if (\r\n !Number.isFinite(parsed) ||\r\n (parsed < 1 && parsed !== ALL_PAGES_VALUE)\r\n ) {\r\n return;\r\n }\r\n\r\n const newParams = new URLSearchParams(searchParams);\r\n newParams.set(pageKey, \"1\");\r\n newParams.set(perPageKey, String(parsed));\r\n setSearchParams(newParams, { replace: true });\r\n onPageSizeChange?.(parsed);\r\n };\r\n\r\n const createPageButtons = () => {\r\n const buttons: ReactNode[] = [];\r\n const maxButtons = 5;\r\n const totalPages = Math.max(1, paginationData?.pageCount ?? 1);\r\n\r\n let startPage = Math.max(0, currentPage - Math.floor(maxButtons / 2));\r\n let endPage = Math.min(totalPages - 1, startPage + maxButtons - 1);\r\n\r\n if (endPage - startPage + 1 < maxButtons) {\r\n startPage = Math.max(0, endPage - maxButtons + 1);\r\n }\r\n\r\n if (startPage > 0) {\r\n buttons.push(\r\n <button\r\n key=\"1\"\r\n type=\"button\"\r\n onClick={() => handlePageChange(0)}\r\n aria-label=\"Page 1\"\r\n className={cn(\r\n \"px-3 py-2 text-sm text-gray-600 hover:text-blue-600 hover:bg-blue-50 rounded-md transition-colors\",\r\n classNames?.pageButton\r\n )}\r\n >\r\n 1\r\n </button>\r\n );\r\n\r\n if (startPage > 1) {\r\n buttons.push(\r\n <span\r\n key=\"ellipsis1\"\r\n aria-hidden=\"true\"\r\n className=\"px-2 py-2 text-gray-400\"\r\n >\r\n ...\r\n </span>\r\n );\r\n }\r\n }\r\n\r\n for (let i = startPage; i <= endPage; i++) {\r\n const isActive = currentPage === i;\r\n buttons.push(\r\n <button\r\n key={i + 1}\r\n type=\"button\"\r\n onClick={() => handlePageChange(i)}\r\n aria-label={`Page ${i + 1}`}\r\n aria-current={isActive ? \"page\" : undefined}\r\n className={cn(\r\n \"px-3 py-2 text-sm rounded-md transition-colors\",\r\n isActive\r\n ? cn(\"bg-gray-400 text-white\", classNames?.activePageButton)\r\n : cn(\r\n \"text-gray-600 hover:text-gray-600 hover:bg-gray-50\",\r\n classNames?.pageButton\r\n )\r\n )}\r\n >\r\n {i + 1}\r\n </button>\r\n );\r\n }\r\n\r\n if (endPage < totalPages - 1) {\r\n if (endPage < totalPages - 2) {\r\n buttons.push(\r\n <span\r\n key=\"ellipsis2\"\r\n aria-hidden=\"true\"\r\n className=\"px-2 py-2 text-gray-400\"\r\n >\r\n ...\r\n </span>\r\n );\r\n }\r\n\r\n buttons.push(\r\n <button\r\n key={totalPages}\r\n type=\"button\"\r\n onClick={() => handlePageChange(totalPages - 1)}\r\n aria-label={`Page ${totalPages}`}\r\n className={cn(\r\n \"px-3 py-2 text-sm text-gray-600 hover:text-gray-600 hover:bg-gray-50 rounded-md transition-colors\",\r\n classNames?.pageButton\r\n )}\r\n >\r\n {totalPages}\r\n </button>\r\n );\r\n }\r\n\r\n return buttons;\r\n };\r\n\r\n if (isLoading || !paginationData) {\r\n return (\r\n <div className=\"flex items-center justify-center p-6 bg-gray-50\">\r\n <span className=\"text-gray-500\">\r\n {isLoading ? \"Loading...\" : \"No pagination data\"}\r\n </span>\r\n </div>\r\n );\r\n }\r\n\r\n const effectiveSizeOptions =\r\n paginationData.perPage > 0 &&\r\n !pageSizeOptions.includes(paginationData.perPage)\r\n ? [...pageSizeOptions, paginationData.perPage].sort((a, b) => a - b)\r\n : pageSizeOptions;\r\n\r\n const selectValue = isShowingAll\r\n ? ALL_PAGES_VALUE\r\n : paginationData.perPage ||\r\n (Number.isFinite(perPageNumber) && perPageNumber > 0\r\n ? perPageNumber\r\n : 10);\r\n\r\n const startItem =\r\n paginationData.totalCount === 0\r\n ? 0\r\n : (paginationData.currentPage - 1) * paginationData.perPage + 1;\r\n const endItem = Math.min(\r\n startItem + paginationData.perPage - 1,\r\n paginationData.totalCount\r\n );\r\n\r\n const { isLayoutLoading, isLayoutSaving, isLayoutResetting } =\r\n layoutStatus ?? {};\r\n const isLayoutBusy =\r\n isLayoutLoading || isLayoutSaving || isLayoutResetting;\r\n\r\n return (\r\n <div\r\n className={cn(\r\n \"flex items-center justify-between pb-4\",\r\n className,\r\n classNames?.root\r\n )}\r\n >\r\n <div className={cn(\"flex-1\", classNames?.info)}>\r\n <span className=\"text-xs font-medium text-neutral-400\">\r\n {isShowingAll\r\n ? `Showing All ${paginationData.totalCount ?? 0} Results`\r\n : `Showing ${padCount(startItem)} - ${padCount(endItem)} of ${paginationData.totalCount ?? 0} results`}\r\n </span>\r\n </div>\r\n\r\n <nav\r\n aria-label=\"Pagination\"\r\n className={cn(\"flex items-center space-x-1\", classNames?.nav)}\r\n >\r\n <button\r\n type=\"button\"\r\n onClick={() => handlePageChange(currentPage - 1)}\r\n disabled={currentPage === 0 || isShowingAll}\r\n className=\"p-2 text-gray-400 hover:text-gray-600 disabled:opacity-30 disabled:cursor-not-allowed transition-colors\"\r\n aria-label=\"Previous page\"\r\n >\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\r\n <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\" />\r\n </svg>\r\n </button>\r\n\r\n <div className=\"flex items-center space-x-1\">\r\n {isShowingAll ? (\r\n <span className=\"px-3 py-2 text-sm text-gray-400\" aria-hidden=\"true\">\r\n All\r\n </span>\r\n ) : (\r\n createPageButtons()\r\n )}\r\n </div>\r\n\r\n <button\r\n type=\"button\"\r\n onClick={() => handlePageChange(currentPage + 1)}\r\n disabled={\r\n currentPage >= paginationData.pageCount - 1 || isShowingAll\r\n }\r\n className=\"p-2 text-gray-400 hover:text-gray-600 disabled:opacity-30 disabled:cursor-not-allowed transition-colors\"\r\n aria-label=\"Next page\"\r\n >\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\r\n <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\" />\r\n </svg>\r\n </button>\r\n </nav>\r\n\r\n <div className=\"flex-1 flex justify-end\">\r\n <div className=\"flex items-center gap-3\">\r\n {onResetLayout &&\r\n (renderResetControl ? (\r\n renderResetControl(onResetLayout)\r\n ) : (\r\n <ResetColumnsButton\r\n onReset={onResetLayout}\r\n disabled={isLayoutBusy}\r\n isLoading={isLoading}\r\n />\r\n ))}\r\n <div className=\"flex items-center space-x-2\">\r\n <label\r\n htmlFor=\"pagination-per-page\"\r\n className=\"text-sm text-gray-600\"\r\n >\r\n Items per page\r\n </label>\r\n <select\r\n id=\"pagination-per-page\"\r\n value={selectValue}\r\n onChange={handlePageSizeChange}\r\n className={cn(\r\n \"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\",\r\n classNames?.select\r\n )}\r\n >\r\n {showAllPagesOption && (\r\n <option value={ALL_PAGES_VALUE}>All</option>\r\n )}\r\n {effectiveSizeOptions.map((option) => (\r\n <option key={option} value={option}>\r\n {option}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nexport default CustomPagination;\r\n","import toast from \"react-hot-toast\";\r\nimport Swal from \"sweetalert2\";\r\n\r\nexport type RtkQueryError = {\r\n status?: number | string;\r\n originalStatus?: number;\r\n data?: {\r\n errors?: Record<string, string[]>;\r\n message?: string;\r\n title?: string;\r\n };\r\n error?: string;\r\n};\r\n\r\nexport interface HandleApiErrorOptions {\r\n showAlert?: boolean;\r\n fallbackMessage?: string;\r\n}\r\n\r\nexport function formatValidationErrorsHtml(\r\n errors: Record<string, string[]>\r\n): string {\r\n const items = Object.keys(errors).flatMap((field) =>\r\n (errors[field] || []).map((msg) => `<li>${msg}</li>`)\r\n );\r\n return `\r\n <div style=\"text-align:left\">\r\n <p>Please review and correct the following:</p>\r\n <ul style=\"margin:8px 0 0 16px; list-style:disc;\">\r\n ${items.join(\"\")}\r\n </ul>\r\n </div>\r\n `;\r\n}\r\n\r\nfunction showValidationAlert(html: string): void {\r\n void Swal.fire({\r\n title: \"Validation errors\",\r\n html,\r\n icon: \"error\",\r\n confirmButtonText: \"OK\",\r\n showCancelButton: false,\r\n confirmButtonColor: \"#FF7335\",\r\n });\r\n}\r\n\r\n/** Handles RTK Query errors with built-in toast.error or SweetAlert (when showAlert is true). */\r\nexport function handleApiError(\r\n error: RtkQueryError | null | undefined,\r\n { showAlert = false, fallbackMessage }: HandleApiErrorOptions = {}\r\n): void {\r\n if (!error) return;\r\n\r\n const status = error.status ?? error.originalStatus;\r\n const data = error.data;\r\n\r\n if (status === 200) {\r\n return;\r\n }\r\n\r\n if (data?.errors && typeof data.errors === \"object\") {\r\n const errors = data.errors;\r\n\r\n if (showAlert) {\r\n showValidationAlert(formatValidationErrorsHtml(errors));\r\n } else {\r\n Object.keys(errors).forEach((field) => {\r\n (errors[field] || []).forEach((errorMessage) => {\r\n toast.error(errorMessage);\r\n });\r\n });\r\n }\r\n return;\r\n }\r\n\r\n if (status === 404) {\r\n return;\r\n }\r\n\r\n const message =\r\n fallbackMessage ||\r\n data?.message ||\r\n data?.title ||\r\n error.error ||\r\n \"An error occurred. Please try again.\";\r\n\r\n toast.error(message);\r\n}\r\n\r\nexport interface ConfirmationAlertOptions {\r\n title?: string;\r\n text?: string;\r\n icon?: \"warning\" | \"info\" | \"question\" | \"error\" | \"success\";\r\n confirmButtonText?: string;\r\n cancelButtonText?: string;\r\n}\r\n\r\nexport function confirmationAlert(\r\n onConfirm: () => void,\r\n options: ConfirmationAlertOptions = {}\r\n): void {\r\n void Swal.fire({\r\n title: options.title ?? \"Are you sure?\",\r\n text: options.text,\r\n icon: options.icon ?? \"warning\",\r\n showCancelButton: true,\r\n confirmButtonText: options.confirmButtonText ?? \"Yes\",\r\n cancelButtonText: options.cancelButtonText ?? \"Cancel\",\r\n confirmButtonColor: \"#FF7335\",\r\n }).then((result) => {\r\n if (result.isConfirmed) {\r\n onConfirm();\r\n }\r\n });\r\n}\r\n","import { useSearchParams } from \"react-router-dom\";\r\nimport { cn } from \"../../utils/cn\";\r\nimport type {\r\n ResetFiltersButtonProps,\r\n ResetFiltersButtonVariant,\r\n} from \"./types\";\r\n\r\nconst BASE_STYLES =\r\n \"inline-flex items-center gap-1.5 px-5 py-3 rounded-md text-sm font-medium transition-colors duration-200 focus:outline-none disabled:cursor-not-allowed disabled:opacity-50\";\r\n\r\nconst VARIANTS: Record<ResetFiltersButtonVariant, string> = {\r\n primary:\r\n \"bg-white text-secondary border border-secondary hover:bg-lightGray hover:text-black\",\r\n \"primary-outline\":\r\n \"bg-white text-primary-150 border border-primary-150 font-bold hover:bg-primary-100 hover:text-white\",\r\n \"primary-fill\":\r\n \"bg-primary-150 text-white border border-primary-150 hover:bg-primary/90\",\r\n secondary:\r\n \"bg-primary-150 text-white border border-primary-150 hover:bg-primary/90\",\r\n danger: \"bg-red-600 text-white border border-red-600 hover:bg-red-700\",\r\n outline: \"bg-white text-primary border border-primary hover:bg-primary/10\",\r\n ghost:\r\n \"bg-transparent text-secondary border border-transparent hover:bg-primary/10\",\r\n};\r\n\r\nfunction ResetIcon({\r\n size = 16,\r\n className,\r\n}: {\r\n size?: number;\r\n className?: string;\r\n}) {\r\n return (\r\n <svg\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n aria-hidden=\"true\"\r\n className={className}\r\n >\r\n <path d=\"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8\" />\r\n <path d=\"M21 3v5h-5\" />\r\n <path d=\"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16\" />\r\n <path d=\"M8 16H3v5\" />\r\n </svg>\r\n );\r\n}\r\n\r\nexport function ResetFiltersButton({\r\n label = \"Reset Filters\",\r\n showLabel = true,\r\n icon,\r\n variant = \"primary-outline\",\r\n className,\r\n onReset,\r\n disabled = false,\r\n}: ResetFiltersButtonProps) {\r\n const [, setSearchParams] = useSearchParams();\r\n\r\n const handleReset = () => {\r\n setSearchParams({}, { replace: true });\r\n onReset?.();\r\n };\r\n\r\n const resolvedIcon = icon === undefined ? <ResetIcon size={16} /> : icon;\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={handleReset}\r\n disabled={disabled}\r\n className={cn(BASE_STYLES, VARIANTS[variant], className)}\r\n >\r\n {resolvedIcon}\r\n {showLabel && label}\r\n </button>\r\n );\r\n}\r\n","import {\r\n useEffect,\r\n useRef,\r\n useState,\r\n type ChangeEvent,\r\n type FormEvent,\r\n} from \"react\";\r\nimport { FiSearch } from \"react-icons/fi\";\r\nimport { useSearchParams } from \"react-router-dom\";\r\nimport { cn } from \"../../utils/cn\";\r\nimport type { SearchInputProps } from \"./types\";\r\n\r\nexport function SearchInput({\r\n placeholder = \"Search...\",\r\n searchBtn = \"\",\r\n searchClassName = \"\",\r\n searchWrapperClass = \"\",\r\n searchIconClassName = \"\",\r\n defaultParam = \"query\",\r\n showIcon = true,\r\n name = \"search\",\r\n type = \"search\",\r\n liveSearch = false,\r\n debounceDelay = 500,\r\n customIcon = null,\r\n defaultValue,\r\n ...props\r\n}: SearchInputProps) {\r\n const [searchParams, setSearchParams] = useSearchParams();\r\n const queryParam = searchParams.get(defaultParam) || defaultValue || \"\";\r\n\r\n const [inputValue, setInputValue] = useState(queryParam);\r\n const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n\r\n const updateSearchParams = (searchQuery: string) => {\r\n if (searchQuery?.trim()) {\r\n setSearchParams((prev) => {\r\n prev.set(defaultParam, searchQuery.trim());\r\n return prev;\r\n });\r\n } else {\r\n setSearchParams((prev) => {\r\n prev.delete(defaultParam);\r\n return prev;\r\n });\r\n }\r\n };\r\n\r\n const handleSearch = (e: FormEvent<HTMLFormElement>) => {\r\n e.preventDefault();\r\n const formData = new FormData(e.currentTarget);\r\n const searchQuery = formData.get(name);\r\n updateSearchParams(String(searchQuery ?? \"\"));\r\n };\r\n\r\n const handleInputChange = (e: ChangeEvent<HTMLInputElement>) => {\r\n const value = e.target.value;\r\n setInputValue(value);\r\n\r\n if (liveSearch) {\r\n if (debounceTimerRef.current) {\r\n clearTimeout(debounceTimerRef.current);\r\n }\r\n\r\n debounceTimerRef.current = setTimeout(() => {\r\n updateSearchParams(value);\r\n }, debounceDelay);\r\n }\r\n\r\n if (value === \"\") {\r\n if (debounceTimerRef.current) {\r\n clearTimeout(debounceTimerRef.current);\r\n }\r\n setInputValue(\"\");\r\n updateSearchParams(\"\");\r\n }\r\n };\r\n\r\n useEffect(() => {\r\n setInputValue(queryParam);\r\n }, [queryParam]);\r\n\r\n useEffect(() => {\r\n return () => {\r\n if (debounceTimerRef.current) {\r\n clearTimeout(debounceTimerRef.current);\r\n }\r\n };\r\n }, []);\r\n\r\n return (\r\n <form\r\n onSubmit={handleSearch}\r\n className={cn(\r\n \"flex items-center justify-between bg-white rounded-md px-2 h-11\",\r\n searchWrapperClass\r\n )}\r\n >\r\n {showIcon && (\r\n <button\r\n type=\"submit\"\r\n className={cn(\r\n \"bg-white text-secondary rounded-full flex items-center justify-center w-10 h-10\",\r\n searchBtn\r\n )}\r\n >\r\n {customIcon ? (\r\n customIcon\r\n ) : (\r\n <FiSearch\r\n className={cn(\"h-5 w-5 text-gray-400\", searchIconClassName)}\r\n />\r\n )}\r\n </button>\r\n )}\r\n <input\r\n value={inputValue}\r\n onChange={handleInputChange}\r\n name={name}\r\n type={type}\r\n className={cn(\"outline-none text-sm w-96\", searchClassName)}\r\n placeholder={placeholder}\r\n {...props}\r\n />\r\n </form>\r\n );\r\n}\r\n","import { AnimatePresence, motion } from \"framer-motion\";\r\nimport { useEffect, useRef, type MouseEvent } from \"react\";\r\nimport { createPortal } from \"react-dom\";\r\nimport { FaFileExport, FaPrint } from \"react-icons/fa\";\r\nimport { IoCloseCircleOutline } from \"react-icons/io5\";\r\nimport { cn } from \"../../utils/cn\";\r\nimport { Loader } from \"../Loader\";\r\nimport type { ModalProps } from \"./types\";\r\n\r\nexport function Modal({\r\n isOpen,\r\n onClose,\r\n title,\r\n children,\r\n footer,\r\n className = \"w-2/3\",\r\n width,\r\n onPrint,\r\n onExport,\r\n modalBodyClassName,\r\n modalBodyWrapperClass,\r\n closeOnBackdropClick = false,\r\n closeOnEscape = true,\r\n zIndex = 1000,\r\n isLoading = false,\r\n customLoader = null,\r\n footerClassName,\r\n}: ModalProps) {\r\n const modalRef = useRef<HTMLDivElement>(null);\r\n\r\n const handleBackdropClick = (e: MouseEvent<HTMLDivElement>) => {\r\n if (e.target === e.currentTarget && closeOnBackdropClick) {\r\n onClose();\r\n }\r\n };\r\n\r\n useEffect(() => {\r\n const handleEscape = (e: KeyboardEvent) => {\r\n if (e.key === \"Escape\" && isOpen && closeOnEscape) {\r\n onClose();\r\n }\r\n };\r\n\r\n if (isOpen) {\r\n document.addEventListener(\"keydown\", handleEscape);\r\n document.body.style.overflow = \"hidden\";\r\n }\r\n\r\n return () => {\r\n document.removeEventListener(\"keydown\", handleEscape);\r\n document.body.style.overflow = \"unset\";\r\n };\r\n }, [isOpen, onClose, closeOnEscape]);\r\n\r\n const modalContent = (\r\n <AnimatePresence>\r\n {isOpen && (\r\n <div\r\n className=\"fixed inset-0 bg-gray-500 bg-opacity-50 flex justify-center items-center z-1000 p-4\"\r\n onClick={handleBackdropClick}\r\n style={{\r\n // Ensure it covers the entire viewport, even in micro frontend context\r\n position: \"fixed\",\r\n top: 0,\r\n left: 0,\r\n right: 0,\r\n bottom: 0,\r\n width: \"100vw\",\r\n height: \"100vh\",\r\n margin: 0,\r\n padding: \"1rem\",\r\n zIndex: zIndex,\r\n }}\r\n >\r\n <motion.div\r\n ref={modalRef}\r\n initial={{ y: \"-100vh\", opacity: 0 }}\r\n animate={{ y: 0, opacity: 1 }}\r\n exit={{ y: \"100vh\", opacity: 0 }}\r\n transition={{ duration: 0.3 }}\r\n className={cn(\r\n `bg-white rounded-3xl shadow-lg max-h-[90vh] flex flex-col mx-auto`,\r\n className,\r\n width,\r\n )}\r\n onClick={(e) => e.stopPropagation()} // Prevent backdrop click when clicking modal content\r\n style={{\r\n maxWidth: \"95vw\", // Ensure modal doesn't exceed viewport width\r\n maxHeight: \"90vh\", // Ensure modal doesn't exceed viewport height\r\n }}\r\n >\r\n {/* Modal Header */}\r\n <div\r\n style={{\r\n borderRadius: \"24px 24px 0 0\",\r\n }}\r\n className=\"sticky top-0 z-10 flex justify-between items-center bg-white text-2xl p-8 pb-4 rounded-t-3xl\"\r\n >\r\n <h2 className=\"font-semibold\">{title}</h2>\r\n <div className=\"flex items-center space-x-4\">\r\n {onPrint && (\r\n <button\r\n onClick={onPrint}\r\n className=\"flex items-center gap-1 hover:text-gray-300 text-sm border p-1 rounded\"\r\n >\r\n <FaPrint name=\"FaPrint\" />\r\n <span>Print</span>\r\n </button>\r\n )}\r\n {onExport && (\r\n <button\r\n onClick={onExport}\r\n className=\"flex items-center gap-1 hover:text-gray-300 text-sm border p-1 rounded\"\r\n >\r\n <FaFileExport />\r\n <span>Export</span>\r\n </button>\r\n )}\r\n <button\r\n onClick={onClose}\r\n className=\"px-2 hover:opacity-70 transition-opacity\"\r\n >\r\n <IoCloseCircleOutline color=\"#8898AA\" size={25} />\r\n </button>\r\n </div>\r\n </div>\r\n <div\r\n className={cn(\r\n \"overflow-y-auto px-8 pb-8 grow scroll scrollbar-hidden\",\r\n modalBodyWrapperClass,\r\n )}\r\n >\r\n {children}\r\n </div>\r\n\r\n {/* Modal Footer */}\r\n {footer && (\r\n\r\n <div\r\n className={cn(\"sticky bottom-0 flex justify-end p-4 space-x-4 border-t bg-white \",footerClassName)}\r\n\r\n style={{\r\n zIndex: 1000,\r\n \r\n borderRadius: \"24px\",\r\n }}\r\n >\r\n {footer}\r\n </div>\r\n )}\r\n </motion.div>\r\n {isLoading && (\r\n <div\r\n className=\"fixed inset-0 flex items-center justify-center bg-gray-200/60\"\r\n style={{ zIndex: 1100 }}\r\n aria-busy=\"true\"\r\n aria-live=\"polite\"\r\n role=\"status\"\r\n onClick={(e) => e.stopPropagation()}\r\n >\r\n {customLoader ? customLoader : <Loader size=\"48px\" />}\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </AnimatePresence>\r\n );\r\n\r\n let modalRoot = document.getElementById(\"modal-root\");\r\n if (!modalRoot) {\r\n modalRoot = document.createElement(\"div\");\r\n modalRoot.id = \"modal-root\";\r\n document.body.appendChild(modalRoot);\r\n }\r\n\r\n return createPortal(modalContent, modalRoot);\r\n}\r\n","import React from 'react';\r\nimport './Loader.css';\r\nimport { LoaderProps } from './Loader.types';\r\n\r\nexport const Loader: React.FC<LoaderProps> = ({ className, color = \"#F54C00\", size = '50px', speed = '1s' }) => {\r\n return (\r\n <div className={`loader`}>\r\n <div \r\n className={`spinner ${className}`} \r\n style={{\r\n border: `4px solid rgba(0, 0, 0, 0.1)`,\r\n borderWidth: '4px',\r\n borderLeftColor: color,\r\n width: size,\r\n height: size,\r\n animation: `spin ${speed} linear infinite`\r\n }}\r\n ></div>\r\n </div>\r\n );\r\n};"],"mappings":"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","names":["clsx","Swal","import_jsx_runtime","import_react_router_dom","import_jsx_runtime","import_react","import_react_router_dom","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime"]}
|
|
@@ -5,8 +5,9 @@ import {
|
|
|
5
5
|
Modal,
|
|
6
6
|
ResetColumnsButton,
|
|
7
7
|
ResetFiltersButton,
|
|
8
|
+
SearchInput,
|
|
8
9
|
TableLayoutToolbarControls
|
|
9
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-J6FBBM4R.mjs";
|
|
10
11
|
import "../chunk-5OG22DIX.mjs";
|
|
11
12
|
export {
|
|
12
13
|
CustomPagination,
|
|
@@ -15,6 +16,7 @@ export {
|
|
|
15
16
|
Modal,
|
|
16
17
|
ResetColumnsButton,
|
|
17
18
|
ResetFiltersButton,
|
|
19
|
+
SearchInput,
|
|
18
20
|
TableLayoutToolbarControls
|
|
19
21
|
};
|
|
20
22
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { ConfirmationAlertOptions, HandleApiErrorOptions, RtkQueryError, capitalizeText, checkIfExistsInArray, cn, confirmationAlert, convertCommaDataToArray, currencyFormatter, deserializeJson, flattenTableData, formatDate, formatDateTime, formatNumber, formatValidationErrorsHtml, getApiError, getErrorMessages, getFieldsByCategory, getFieldsByInputType, getFieldsByName, handleApiError, isEmpty, normalizeApiListItems, parseCurrencyValueToNumber, removeByPropertyValues, toDateInputValue, toLowerCaseText, truncateFileName, truncateText } from './utils/index.mjs';
|
|
2
2
|
export { UseGridHeightOptions, useGridHeight, usePaginationUrlSync } from './hooks/index.mjs';
|
|
3
|
-
export { CustomPagination, CustomPaginationClassNames, CustomPaginationProps, EztrakTab, EztrakTabs, EztrakTabsClassNames, EztrakTabsProps, LayoutStatus, Loader, LoaderProps, Modal, ModalProps, PaginationData, ResetColumnsButton, ResetColumnsButtonProps, ResetFiltersButton, ResetFiltersButtonProps, TableLayoutToolbarControls, TableLayoutToolbarControlsProps } from './components/index.mjs';
|
|
3
|
+
export { CustomPagination, CustomPaginationClassNames, CustomPaginationProps, EztrakTab, EztrakTabs, EztrakTabsClassNames, EztrakTabsProps, LayoutStatus, Loader, LoaderProps, Modal, ModalProps, PaginationData, ResetColumnsButton, ResetColumnsButtonProps, ResetFiltersButton, ResetFiltersButtonProps, ResetFiltersButtonVariant, SearchInput, SearchInputProps, 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
1
|
export { ConfirmationAlertOptions, HandleApiErrorOptions, RtkQueryError, capitalizeText, checkIfExistsInArray, cn, confirmationAlert, convertCommaDataToArray, currencyFormatter, deserializeJson, flattenTableData, formatDate, formatDateTime, formatNumber, formatValidationErrorsHtml, getApiError, getErrorMessages, getFieldsByCategory, getFieldsByInputType, getFieldsByName, handleApiError, isEmpty, normalizeApiListItems, parseCurrencyValueToNumber, removeByPropertyValues, toDateInputValue, toLowerCaseText, truncateFileName, truncateText } from './utils/index.js';
|
|
2
2
|
export { UseGridHeightOptions, useGridHeight, usePaginationUrlSync } from './hooks/index.js';
|
|
3
|
-
export { CustomPagination, CustomPaginationClassNames, CustomPaginationProps, EztrakTab, EztrakTabs, EztrakTabsClassNames, EztrakTabsProps, LayoutStatus, Loader, LoaderProps, Modal, ModalProps, PaginationData, ResetColumnsButton, ResetColumnsButtonProps, ResetFiltersButton, ResetFiltersButtonProps, TableLayoutToolbarControls, TableLayoutToolbarControlsProps } from './components/index.js';
|
|
3
|
+
export { CustomPagination, CustomPaginationClassNames, CustomPaginationProps, EztrakTab, EztrakTabs, EztrakTabsClassNames, EztrakTabsProps, LayoutStatus, Loader, LoaderProps, Modal, ModalProps, PaginationData, ResetColumnsButton, ResetColumnsButtonProps, ResetFiltersButton, ResetFiltersButtonProps, ResetFiltersButtonVariant, SearchInput, SearchInputProps, TableLayoutToolbarControls, TableLayoutToolbarControlsProps } from './components/index.js';
|
|
4
4
|
import 'clsx';
|
|
5
5
|
import 'react-router-dom';
|
|
6
6
|
import 'react';
|