@eztrak/shared 0.4.1 → 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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/index.ts","../../src/components/tabs/EztrakTabs.tsx","../../src/utils/cn.ts"],"sourcesContent":["export { EztrakTabs } from \"./tabs/EztrakTabs\";\r\nexport type {\r\n EztrakTab,\r\n EztrakTabsClassNames,\r\n EztrakTabsProps,\r\n} from \"./tabs/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"],"mappings":"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","names":["clsx"]}
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"],"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\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\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 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\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 (!Number.isFinite(parsed) || parsed < 1) {\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 = pageSizeOptions.includes(paginationData.perPage)\r\n ? pageSizeOptions\r\n : [...pageSizeOptions, paginationData.perPage].sort((a, b) => a - b);\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 Showing {padCount(startItem)} - {padCount(endItem)} of{\" \"}\r\n {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}\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\">{createPageButtons()}</div>\r\n\r\n <button\r\n type=\"button\"\r\n onClick={() => handlePageChange(currentPage + 1)}\r\n disabled={currentPage >= paginationData.pageCount - 1}\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={paginationData.perPage || 10}\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 {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"],"mappings":"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","names":["clsx","Swal","import_jsx_runtime"]}
@@ -1,8 +1,14 @@
1
1
  import {
2
- EztrakTabs
3
- } from "../chunk-5RR3BVFN.mjs";
4
- import "../chunk-5L6SERQP.mjs";
2
+ CustomPagination,
3
+ EztrakTabs,
4
+ ResetColumnsButton,
5
+ TableLayoutToolbarControls
6
+ } from "../chunk-2VPBTT7J.mjs";
7
+ import "../chunk-5OG22DIX.mjs";
5
8
  export {
6
- EztrakTabs
9
+ CustomPagination,
10
+ EztrakTabs,
11
+ ResetColumnsButton,
12
+ TableLayoutToolbarControls
7
13
  };
8
14
  //# sourceMappingURL=index.mjs.map
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");
@@ -572,12 +591,332 @@ function EztrakTabs({
572
591
  }) }) : null
573
592
  ] }) });
574
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
+ }
575
910
  // Annotate the CommonJS export names for ESM import in node:
576
911
  0 && (module.exports = {
912
+ CustomPagination,
577
913
  EztrakTabs,
914
+ ResetColumnsButton,
915
+ TableLayoutToolbarControls,
578
916
  capitalizeText,
579
917
  checkIfExistsInArray,
580
918
  cn,
919
+ confirmationAlert,
581
920
  convertCommaDataToArray,
582
921
  currencyFormatter,
583
922
  deserializeJson,