erp-pro-ui 0.1.2 → 0.1.4
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/animations.css +40 -0
- package/dist/calendar.cjs +1 -1
- package/dist/calendar.mjs +1 -1
- package/dist/card.cjs +1 -1
- package/dist/card.mjs +1 -1
- package/dist/carousel.cjs +1 -1
- package/dist/carousel.mjs +1 -1
- package/dist/catalog.cjs +6 -0
- package/dist/catalog.cjs.map +1 -1
- package/dist/catalog.d.ts +11 -1
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.mjs +6 -0
- package/dist/catalog.mjs.map +1 -1
- package/dist/charts.cjs +2 -1
- package/dist/charts.mjs +2 -2
- package/dist/checkbox.cjs +1 -1
- package/dist/checkbox.mjs +1 -1
- package/dist/chip.cjs +1 -1
- package/dist/chip.mjs +1 -1
- package/dist/chroma-grid.cjs +1 -1
- package/dist/chroma-grid.mjs +1 -1
- package/dist/chunks/{calendar-xrGmvukr.cjs → calendar-Cpp_Rc7T.cjs} +58 -17
- package/dist/chunks/calendar-Cpp_Rc7T.cjs.map +1 -0
- package/dist/chunks/{calendar-BarcG6x_.mjs → calendar-DrCgT_pj.mjs} +58 -17
- package/dist/chunks/calendar-DrCgT_pj.mjs.map +1 -0
- package/dist/chunks/{card-gt-HZh0h.cjs → card-C5_tFK6Q.cjs} +1 -1
- package/dist/chunks/{card-gt-HZh0h.cjs.map → card-C5_tFK6Q.cjs.map} +1 -1
- package/dist/chunks/{card-CcIF6z2H.mjs → card-Dh8wNv8N.mjs} +1 -1
- package/dist/chunks/{card-CcIF6z2H.mjs.map → card-Dh8wNv8N.mjs.map} +1 -1
- package/dist/chunks/{carousel-DJdqBVRK.mjs → carousel-BYwqI4cA.mjs} +1 -1
- package/dist/chunks/{carousel-DJdqBVRK.mjs.map → carousel-BYwqI4cA.mjs.map} +1 -1
- package/dist/chunks/{carousel-Cq5uwqQt.cjs → carousel-C1338X8h.cjs} +1 -1
- package/dist/chunks/{carousel-Cq5uwqQt.cjs.map → carousel-C1338X8h.cjs.map} +1 -1
- package/dist/chunks/{charts-DugYWvEf.mjs → charts-BYvM4TMG.mjs} +371 -117
- package/dist/chunks/charts-BYvM4TMG.mjs.map +1 -0
- package/dist/chunks/{charts-BpElnsoR.cjs → charts-DbxyHtlX.cjs} +375 -115
- package/dist/chunks/charts-DbxyHtlX.cjs.map +1 -0
- package/dist/chunks/{checkbox-yHuSw-hV.cjs → checkbox-CxOcjoGP.cjs} +1 -1
- package/dist/chunks/{checkbox-yHuSw-hV.cjs.map → checkbox-CxOcjoGP.cjs.map} +1 -1
- package/dist/chunks/{checkbox-DvwlGwWe.mjs → checkbox-Pr49U9F1.mjs} +1 -1
- package/dist/chunks/{checkbox-DvwlGwWe.mjs.map → checkbox-Pr49U9F1.mjs.map} +1 -1
- package/dist/chunks/{chip-DcBji__g.cjs → chip-B4ol1yPk.cjs} +1 -1
- package/dist/chunks/{chip-DcBji__g.cjs.map → chip-B4ol1yPk.cjs.map} +1 -1
- package/dist/chunks/{chip-BGSUmnlO.mjs → chip-DdnBLdpl.mjs} +1 -1
- package/dist/chunks/{chip-BGSUmnlO.mjs.map → chip-DdnBLdpl.mjs.map} +1 -1
- package/dist/chunks/{chroma-grid-Cdeql_2C.mjs → chroma-grid-BAo6V5A7.mjs} +1 -1
- package/dist/chunks/{chroma-grid-Cdeql_2C.mjs.map → chroma-grid-BAo6V5A7.mjs.map} +1 -1
- package/dist/chunks/{chroma-grid-9E9j1s9I.cjs → chroma-grid-CIk0dsNS.cjs} +1 -1
- package/dist/chunks/{chroma-grid-9E9j1s9I.cjs.map → chroma-grid-CIk0dsNS.cjs.map} +1 -1
- package/dist/chunks/{color-palette-BLvDnCOD.cjs → color-palette-2TuEMkAn.cjs} +1 -1
- package/dist/chunks/{color-palette-BLvDnCOD.cjs.map → color-palette-2TuEMkAn.cjs.map} +1 -1
- package/dist/chunks/{color-palette-CXlCDiZz.mjs → color-palette-euKQMWlV.mjs} +1 -1
- package/dist/chunks/{color-palette-CXlCDiZz.mjs.map → color-palette-euKQMWlV.mjs.map} +1 -1
- package/dist/chunks/{combobox-BXu3s0dt.cjs → combobox-CwGubKTt.cjs} +2 -2
- package/dist/chunks/combobox-CwGubKTt.cjs.map +1 -0
- package/dist/chunks/{combobox-CjK-qG4k.mjs → combobox-DrFmkI0F.mjs} +2 -2
- package/dist/chunks/combobox-DrFmkI0F.mjs.map +1 -0
- package/dist/chunks/{data-table-DyEQn9Yj.mjs → data-table-Bo80m7qV.mjs} +8 -8
- package/dist/chunks/{data-table-DyEQn9Yj.mjs.map → data-table-Bo80m7qV.mjs.map} +1 -1
- package/dist/chunks/{data-table-9HELVsYR.cjs → data-table-W1sK5tkL.cjs} +8 -8
- package/dist/chunks/{data-table-9HELVsYR.cjs.map → data-table-W1sK5tkL.cjs.map} +1 -1
- package/dist/chunks/{date-picker-D8gaaMlJ.mjs → date-picker-CNPORxhv.mjs} +87 -17
- package/dist/chunks/date-picker-CNPORxhv.mjs.map +1 -0
- package/dist/chunks/{date-picker-W9om1j7A.cjs → date-picker-CZo68Fkl.cjs} +87 -17
- package/dist/chunks/date-picker-CZo68Fkl.cjs.map +1 -0
- package/dist/chunks/input-BWM6G7jq.cjs +117 -0
- package/dist/chunks/input-BWM6G7jq.cjs.map +1 -0
- package/dist/chunks/input-Bt_r_B_c.mjs +105 -0
- package/dist/chunks/input-Bt_r_B_c.mjs.map +1 -0
- package/dist/chunks/{multi-select-combobox-ELSH_Xr4.mjs → multi-select-combobox-D46M-AN9.mjs} +2 -2
- package/dist/chunks/multi-select-combobox-D46M-AN9.mjs.map +1 -0
- package/dist/chunks/{multi-select-combobox-UW0X15W7.cjs → multi-select-combobox-dS6bJE_e.cjs} +2 -2
- package/dist/chunks/multi-select-combobox-dS6bJE_e.cjs.map +1 -0
- package/dist/chunks/{otp-input-B6zzOEqw.cjs → otp-input-DSW9Ca_D.cjs} +2 -2
- package/dist/chunks/otp-input-DSW9Ca_D.cjs.map +1 -0
- package/dist/chunks/{otp-input-Bg4nQG6x.mjs → otp-input-DeAi4nJ_.mjs} +2 -2
- package/dist/chunks/otp-input-DeAi4nJ_.mjs.map +1 -0
- package/dist/chunks/{progress-bar-C9FZDrju.mjs → progress-bar-B9sy7WBT.mjs} +1 -1
- package/dist/chunks/{progress-bar-C9FZDrju.mjs.map → progress-bar-B9sy7WBT.mjs.map} +1 -1
- package/dist/chunks/{progress-bar-C1OvQ-NI.cjs → progress-bar-BdvQtpm3.cjs} +1 -1
- package/dist/chunks/{progress-bar-C1OvQ-NI.cjs.map → progress-bar-BdvQtpm3.cjs.map} +1 -1
- package/dist/chunks/select-B8UQ6Uq5.mjs +170 -0
- package/dist/chunks/select-B8UQ6Uq5.mjs.map +1 -0
- package/dist/chunks/select-CCUSMvfS.cjs +176 -0
- package/dist/chunks/select-CCUSMvfS.cjs.map +1 -0
- package/dist/chunks/skeleton-BNea1Rcp.cjs +422 -0
- package/dist/chunks/skeleton-BNea1Rcp.cjs.map +1 -0
- package/dist/chunks/skeleton-CtLumdRw.mjs +368 -0
- package/dist/chunks/skeleton-CtLumdRw.mjs.map +1 -0
- package/dist/chunks/stepper-D6qQbZdg.cjs +642 -0
- package/dist/chunks/stepper-D6qQbZdg.cjs.map +1 -0
- package/dist/chunks/stepper-DUknuW2E.mjs +618 -0
- package/dist/chunks/stepper-DUknuW2E.mjs.map +1 -0
- package/dist/chunks/{textarea-CU5C-Zw9.mjs → textarea-Blky_fLK.mjs} +2 -2
- package/dist/chunks/{textarea-CU5C-Zw9.mjs.map → textarea-Blky_fLK.mjs.map} +1 -1
- package/dist/chunks/{textarea-CAUsyu4-.cjs → textarea-ok_NlE2p.cjs} +2 -2
- package/dist/chunks/textarea-ok_NlE2p.cjs.map +1 -0
- package/dist/color-palette.cjs +1 -1
- package/dist/color-palette.mjs +1 -1
- package/dist/colors.css +3 -0
- package/dist/combobox.cjs +1 -1
- package/dist/combobox.mjs +1 -1
- package/dist/components/data-display/charts/AreaChart.d.ts.map +1 -1
- package/dist/components/data-display/charts/BarChart.d.ts +1 -0
- package/dist/components/data-display/charts/BarChart.d.ts.map +1 -1
- package/dist/components/data-display/charts/NeonLineChart.d.ts.map +1 -1
- package/dist/components/data-display/charts/PieChart.d.ts +18 -2
- package/dist/components/data-display/charts/PieChart.d.ts.map +1 -1
- package/dist/components/data-display/charts/PositiveNegativeBarChart.d.ts +21 -0
- package/dist/components/data-display/charts/PositiveNegativeBarChart.d.ts.map +1 -0
- package/dist/components/data-display/charts/StackedBarChart.d.ts.map +1 -1
- package/dist/components/data-display/charts/ThinBreakdownBar.d.ts +3 -0
- package/dist/components/data-display/charts/ThinBreakdownBar.d.ts.map +1 -1
- package/dist/components/data-display/charts/chartStyles.d.ts +24 -0
- package/dist/components/data-display/charts/chartStyles.d.ts.map +1 -0
- package/dist/components/data-display/charts/index.d.ts +2 -0
- package/dist/components/data-display/charts/index.d.ts.map +1 -1
- package/dist/components/data-display/skeleton/Skeleton.d.ts +32 -5
- package/dist/components/data-display/skeleton/Skeleton.d.ts.map +1 -1
- package/dist/components/data-display/skeleton/index.d.ts +2 -2
- package/dist/components/data-display/skeleton/index.d.ts.map +1 -1
- package/dist/components/forms/calendar/Calendar.d.ts.map +1 -1
- package/dist/components/forms/date-picker/DatePicker.d.ts.map +1 -1
- package/dist/components/forms/input/Input.d.ts.map +1 -1
- package/dist/components/forms/input/types.d.ts +5 -0
- package/dist/components/forms/input/types.d.ts.map +1 -1
- package/dist/components/forms/select/Select.d.ts.map +1 -1
- package/dist/components/forms/select/types.d.ts +7 -1
- package/dist/components/forms/select/types.d.ts.map +1 -1
- package/dist/components/navigation/stepper/Stepper1.d.ts +4 -0
- package/dist/components/navigation/stepper/Stepper1.d.ts.map +1 -0
- package/dist/components/navigation/stepper/Stepper2.d.ts +5 -0
- package/dist/components/navigation/stepper/Stepper2.d.ts.map +1 -0
- package/dist/components/navigation/stepper/index.d.ts +4 -1
- package/dist/components/navigation/stepper/index.d.ts.map +1 -1
- package/dist/components/navigation/stepper/types.d.ts +85 -0
- package/dist/components/navigation/stepper/types.d.ts.map +1 -1
- package/dist/data-table.cjs +1 -1
- package/dist/data-table.mjs +1 -1
- package/dist/date-picker.cjs +1 -1
- package/dist/date-picker.mjs +1 -1
- package/dist/docs.cjs +12 -2
- package/dist/docs.cjs.map +1 -1
- package/dist/docs.d.ts.map +1 -1
- package/dist/docs.mjs +12 -2
- package/dist/docs.mjs.map +1 -1
- package/dist/foundation.css +7 -0
- package/dist/index.cjs +32 -19
- package/dist/index.d.ts +7 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +20 -20
- package/dist/input.cjs +1 -1
- package/dist/input.mjs +1 -1
- package/dist/multi-select-combobox.cjs +1 -1
- package/dist/multi-select-combobox.mjs +1 -1
- package/dist/otp-input.cjs +1 -1
- package/dist/otp-input.mjs +1 -1
- package/dist/progress-bar.cjs +1 -1
- package/dist/progress-bar.mjs +1 -1
- package/dist/select.cjs +1 -1
- package/dist/select.mjs +1 -1
- package/dist/skeleton.cjs +9 -1
- package/dist/skeleton.mjs +2 -2
- package/dist/stepper.cjs +5 -1
- package/dist/stepper.mjs +2 -2
- package/dist/textarea.cjs +1 -1
- package/dist/textarea.mjs +1 -1
- package/dist/tokens.css +11 -2
- package/package.json +9 -9
- package/dist/chunks/calendar-BarcG6x_.mjs.map +0 -1
- package/dist/chunks/calendar-xrGmvukr.cjs.map +0 -1
- package/dist/chunks/charts-BpElnsoR.cjs.map +0 -1
- package/dist/chunks/charts-DugYWvEf.mjs.map +0 -1
- package/dist/chunks/combobox-BXu3s0dt.cjs.map +0 -1
- package/dist/chunks/combobox-CjK-qG4k.mjs.map +0 -1
- package/dist/chunks/date-picker-D8gaaMlJ.mjs.map +0 -1
- package/dist/chunks/date-picker-W9om1j7A.cjs.map +0 -1
- package/dist/chunks/input-D9qZNqXV.cjs +0 -99
- package/dist/chunks/input-D9qZNqXV.cjs.map +0 -1
- package/dist/chunks/input-wNqevfQ4.mjs +0 -87
- package/dist/chunks/input-wNqevfQ4.mjs.map +0 -1
- package/dist/chunks/multi-select-combobox-ELSH_Xr4.mjs.map +0 -1
- package/dist/chunks/multi-select-combobox-UW0X15W7.cjs.map +0 -1
- package/dist/chunks/otp-input-B6zzOEqw.cjs.map +0 -1
- package/dist/chunks/otp-input-Bg4nQG6x.mjs.map +0 -1
- package/dist/chunks/select-D71tk6-I.mjs +0 -152
- package/dist/chunks/select-D71tk6-I.mjs.map +0 -1
- package/dist/chunks/select-WC_kPqUP.cjs +0 -158
- package/dist/chunks/select-WC_kPqUP.cjs.map +0 -1
- package/dist/chunks/skeleton-BhYWOp0Q.mjs +0 -215
- package/dist/chunks/skeleton-BhYWOp0Q.mjs.map +0 -1
- package/dist/chunks/skeleton-DTXpHYYB.cjs +0 -221
- package/dist/chunks/skeleton-DTXpHYYB.cjs.map +0 -1
- package/dist/chunks/stepper-D4yQsQB0.mjs +0 -261
- package/dist/chunks/stepper-D4yQsQB0.mjs.map +0 -1
- package/dist/chunks/stepper-fY-Sx72k.cjs +0 -267
- package/dist/chunks/stepper-fY-Sx72k.cjs.map +0 -1
- package/dist/chunks/textarea-CAUsyu4-.cjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table-9HELVsYR.cjs","names":[],"sources":["../../src/components/data-display/data-table/DataTable.tsx"],"sourcesContent":["import React from \"react\";\nimport {\n useReactTable,\n getCoreRowModel,\n getPaginationRowModel,\n getFilteredRowModel,\n flexRender,\n type CellContext,\n type ColumnDef,\n type PaginationState,\n type Table,\n} from \"@tanstack/react-table\";\nimport { Chip } from \"../chip\";\nimport { Button } from \"../../forms/button\";\nimport { Combobox } from \"../../forms/combobox\";\nimport { MultiSelectCombobox } from \"../../forms/multi-select-combobox\";\nimport { Checkbox } from \"../../forms/checkbox\";\nimport { Input } from \"../../forms/input\";\nimport { Select } from \"../../forms/select\";\nimport { Switch } from \"../../forms/switch\";\nimport {\n DatePicker,\n type DatePickerValue,\n type DateRangeValue,\n} from \"../../forms/date-picker\";\nimport {\n ChevronLeftIcon,\n ChevronRightIcon,\n ChevronsLeftIcon,\n ChevronsRightIcon,\n EllipsisVerticalIcon,\n FilterIcon,\n FilterProfileIcon,\n FilterXIcon,\n LoaderIcon,\n RefreshIcon,\n SearchIcon,\n SelectionIcon,\n SettingsIcon,\n TrashIcon,\n} from \"../../icons\";\n\n// Filter option type - can be static or async\nexport interface FilterOption {\n id: string;\n label: string;\n type?:\n | \"text\"\n | \"select\"\n | \"combobox\"\n | \"checkbox\"\n | \"switch\"\n | \"date\"\n | \"date-range\"\n | \"number-range\";\n placeholder?: string;\n options?: string[]; // Static options\n // Async options support\n queryKey?: string | string[]; // React Query key for caching\n fetchOptions?: () => Promise<string[]>; // Async function to fetch options\n isLoading?: boolean; // Loading state (managed externally)\n multiple?: boolean; // Enable multi-select\n /* Crystal UI Unification */\n /*\n ### Automated Browser Testing\n The filters were verified using the browser subagent, confirming that each filter type correctly updates the table data in real-time and adheres to our new unified \"Crystal\" aesthetic.\n\n ````carousel\n \n <!-- slide -->\n \n <!-- slide -->\n \n ````\n\n ### Key Successes:\n - **Unified Aesthetic**: All components now share a consistent `backdrop-blur-xl` and semi-transparent background.\n - **Improved Visual Hierarchy**: The crystal effect makes the components feel integrated with the page while still being clearly interactive.\n - **Robust Logic**: Maintained all advanced filtering logic (date ranges, numeric ranges, partial matches) while upgrading the visual layer.\n */\n}\n\n// Filter value can be single string, array of strings, or range objects\nexport type FilterValue =\n | string\n | string[]\n | boolean\n | DatePickerValue\n | { min?: number; max?: number };\nexport type FilterValues = Record<string, FilterValue>;\n\nexport interface DataTableBulkActionContext<T> {\n selectedRows: T[];\n selectedCount: number;\n clearSelection: () => void;\n disableBulkSelection: () => void;\n}\n\nexport interface DataTableCellRenderContext<T> {\n value: unknown;\n row: T;\n rowIndex: number;\n columnId: string;\n}\n\nexport interface DataTableColumn<T> {\n id: string;\n label: string;\n visible?: boolean;\n filterable?: boolean;\n multiFilter?: boolean;\n priority?: number;\n renderCell?: (context: DataTableCellRenderContext<T>) => React.ReactNode;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface DataTableProps<T = Record<string, any>> {\n columns: DataTableColumn<T>[];\n data: T[];\n isLoading?: boolean; // Table data loading state\n onColumnToggle?: (columnId: string) => void;\n /** Number of items per page */\n pageSize?: number;\n /** Maximum height for the scrollable table area */\n maxHeight?: string;\n onSearch?: (query: string) => void;\n onExport?: () => void;\n onRowAction?: (action: string, row: T) => void;\n onBulkDelete?: (rows: T[]) => void;\n renderBulkActions?: (\n context: DataTableBulkActionContext<T>,\n ) => React.ReactNode;\n renderBulkActionCard?: (\n context: DataTableBulkActionContext<T>,\n ) => React.ReactNode;\n onFilterChange?: (filters: FilterValues) => void;\n // Filter options - can include async filters\n filterOptions?: FilterOption[];\n // Called when filters are applied (for server-side filtering)\n onFiltersApply?: (filters: FilterValues) => void;\n // Enable server-side filtering mode\n serverSideFiltering?: boolean;\n searchPlaceholder?: string;\n children?: React.ReactNode;\n /** Total row count for server-side pagination */\n totalCount?: number;\n /** Callback when pagination changes (for server-side pagination) */\n onPaginationChange?: (pageIndex: number, pageSize: number) => void;\n}\n\nfunction renderDefaultCellValue(value: unknown): React.ReactNode {\n if (value === undefined || value === null || value === \"\") {\n return \"-\";\n }\n\n if (typeof value === \"boolean\") {\n return value ? \"Yes\" : \"No\";\n }\n\n if (Array.isArray(value)) {\n return value.length > 0 ? value.join(\", \") : \"-\";\n }\n\n return value as React.ReactNode;\n}\n\ninterface FilterDropdownProps {\n isOpen: boolean;\n onClose: () => void;\n children: React.ReactNode;\n}\n\nexport const FilterDropdown: React.FC<FilterDropdownProps> = ({\n isOpen,\n onClose,\n children,\n}) => {\n if (!isOpen) return null;\n\n return (\n <>\n <div\n className=\"fixed inset-0 z-40\"\n onClick={onClose}\n aria-hidden=\"true\"\n />\n <div className=\"absolute top-full right-0 z-50 mt-2 min-w-64 overflow-hidden rounded-[4px] border border-white/45 bg-neutral-50 shadow-[0_18px_40px_rgba(15,23,42,0.18)] ring-1 ring-inset ring-white/35 backdrop-blur-2xl dark:border-white/10 dark:bg-neutral-800/50 dark:shadow-[0_22px_48px_rgba(0,0,0,0.42)] dark:ring-white/6\">\n {children}\n </div>\n </>\n );\n};\n\ninterface FilterButtonProps {\n icon: React.ReactNode;\n label: string;\n onClick: () => void;\n hasActive?: boolean;\n}\n\nexport const FilterButton: React.FC<FilterButtonProps> = ({\n icon,\n label,\n onClick,\n hasActive,\n}) => (\n <Button\n onClick={onClick}\n title={label}\n aria-label={label}\n className={`h-10 min-w-10 px-0 py-0 shadow-none ${\n hasActive\n ? \"border-accent/20 bg-accent-subtle text-accent hover:bg-accent-subtle hover:opacity-100\"\n : \"border-transparent bg-transparent text-neutral-600 hover:bg-neutral-100 hover:text-neutral-700 hover:opacity-100 dark:text-neutral-400 dark:hover:bg-neutral-700 dark:hover:text-neutral-200\"\n }`}\n >\n {icon}\n </Button>\n);\n\ninterface ColumnToggleProps {\n columns: {\n id: string;\n label: string;\n visible?: boolean;\n }[];\n onToggle: (columnId: string) => void;\n onShowAll?: () => void;\n onHideAll?: () => void;\n}\n\nexport const ColumnToggle: React.FC<ColumnToggleProps> = ({\n columns,\n onToggle,\n onShowAll,\n onHideAll,\n}) => (\n <div className=\"p-4 space-y-3\">\n <div className=\"flex items-center justify-between mb-3\">\n <span className=\"text-sm font-semibold text-neutral-900 dark:text-white\">\n COLUMNS\n </span>\n </div>\n\n <div className=\"space-y-2 max-h-64 overflow-y-auto\">\n {columns.map((col) => (\n <div\n key={col.id}\n className=\"rounded-[8px] px-2 py-1 hover:bg-neutral-100 dark:hover:bg-neutral-700\"\n >\n <Checkbox\n checked={col.visible !== false}\n onChange={() => onToggle(col.id)}\n label={col.label}\n />\n </div>\n ))}\n </div>\n\n {(onShowAll || onHideAll) && (\n <div className=\"flex gap-2 border-t border-neutral-200 pt-2 dark:border-neutral-700\">\n {onShowAll && (\n <Button\n onClick={onShowAll}\n size=\"small\"\n className=\"flex-1 border-none bg-transparent px-1 py-1 text-xs font-semibold text-accent shadow-none hover:bg-transparent hover:text-accent-hover hover:opacity-100\"\n >\n SHOW ALL\n </Button>\n )}\n {onHideAll && (\n <Button\n onClick={onHideAll}\n size=\"small\"\n className=\"flex-1 border-none bg-transparent px-1 py-1 text-xs font-semibold text-neutral-500 shadow-none hover:bg-transparent hover:text-neutral-600 hover:opacity-100 dark:text-neutral-300 dark:hover:text-white\"\n >\n HIDE ALL\n </Button>\n )}\n </div>\n )}\n </div>\n);\n\ninterface FilterProfileProps {\n isOpen: boolean;\n onClose: () => void;\n onSaveProfile: (name: string) => void;\n}\n\nexport const FilterProfile: React.FC<FilterProfileProps> = ({\n isOpen,\n onClose,\n onSaveProfile,\n}) => {\n const [profileName, setProfileName] = React.useState(\"\");\n\n const handleSave = () => {\n if (profileName.trim()) {\n onSaveProfile(profileName);\n setProfileName(\"\");\n onClose();\n }\n };\n\n if (!isOpen) return null;\n\n return (\n <div\n className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\"\n onClick={onClose}\n >\n <div\n className=\"bg-white dark:bg-neutral-800 rounded-xl p-6 max-w-md w-full mx-4\"\n onClick={(e) => e.stopPropagation()}\n >\n <h2 className=\"text-2xl font-bold text-neutral-900 dark:text-white mb-4\">\n Add new profile\n </h2>\n\n <label className=\"mb-2 block text-sm font-medium text-accent\">\n Enter filter profile name:\n </label>\n <Input\n type=\"text\"\n value={profileName}\n onChange={(e) => setProfileName(e.target.value)}\n placeholder=\"Enter value\"\n className=\"\"\n onKeyDown={(e) => e.key === \"Enter\" && handleSave()}\n />\n\n <div className=\"flex justify-end gap-3 mt-6\">\n <Button onClick={onClose} className=\"min-w-28\" size=\"medium\">\n Cancel\n </Button>\n <Button\n onClick={handleSave}\n disabled={!profileName.trim()}\n className=\"min-w-28\"\n size=\"medium\"\n primary\n >\n Save\n </Button>\n </div>\n </div>\n </div>\n );\n};\n\ntype AsyncFilterOptionsState = Record<\n string,\n { options: string[]; isLoading: boolean }\n>;\n\ntype NumberRangeFilterValue = { min?: number; max?: number };\n\nconst ICON_BUTTON_CLASS_NAME =\n \"inline-flex items-center justify-center rounded-lg text-neutral-400 transition-colors hover:bg-neutral-100 hover:text-neutral-600 dark:hover:bg-neutral-700\";\nconst DISABLED_ICON_BUTTON_CLASS_NAME = `${ICON_BUTTON_CLASS_NAME} disabled:opacity-40 disabled:cursor-not-allowed`;\nconst TABLE_CONTROL_ICON_CLASS_NAME = \"h-[18px] w-[18px] shrink-0\";\nconst TABLE_COMPLEX_ICON_CLASS_NAME = \"h-5 w-5 shrink-0\";\n\nconst isFilterValueEmpty = (value?: FilterValue | null): boolean => {\n if (value === undefined || value === null) {\n return true;\n }\n\n if (typeof value === \"string\") {\n return value === \"\";\n }\n\n if (Array.isArray(value)) {\n return value.length === 0;\n }\n\n if (value instanceof Date || typeof value === \"boolean\") {\n return false;\n }\n\n if (\"start\" in value || \"end\" in value) {\n const rangeValue = value as DateRangeValue;\n return !rangeValue.start && !rangeValue.end;\n }\n\n return value.min === undefined && value.max === undefined;\n};\n\nconst isFilterActive = (value?: FilterValue): boolean =>\n !isFilterValueEmpty(value);\n\nconst toSelectOptions = (options?: string[]) =>\n (options || []).map((option) => ({\n value: option,\n label: option,\n }));\n\nconst getStringFilterValue = (value?: FilterValue): string =>\n typeof value === \"string\" ? value : \"\";\n\nconst getMultiStringFilterValue = (value?: FilterValue): string[] => {\n if (Array.isArray(value)) {\n return value;\n }\n\n return typeof value === \"string\" && value ? [value] : [];\n};\n\nconst getNumberRangeFilterValue = (\n value?: FilterValue,\n): NumberRangeFilterValue => {\n if (\n !value ||\n typeof value !== \"object\" ||\n \"start\" in value ||\n \"end\" in value\n ) {\n return {};\n }\n\n return value as NumberRangeFilterValue;\n};\n\nconst getDateFilterValue = (value?: FilterValue): DatePickerValue =>\n value instanceof Date || value === null ? value : null;\n\nconst getDateRangeFilterValue = (value?: FilterValue): DateRangeValue => {\n if (\n value &&\n typeof value === \"object\" &&\n \"start\" in value &&\n \"end\" in value\n ) {\n return value as DateRangeValue;\n }\n\n return { start: null, end: null };\n};\n\nfunction buildGeneratedFilterOptions<T>(\n columns: DataTableProps<T>[\"columns\"],\n data: T[],\n): FilterOption[] {\n return columns\n .filter((column) => column.filterable !== false)\n .map((column) => {\n const uniqueValues = new Set<string>();\n\n data.forEach((row) => {\n const value = (row as Record<string, unknown>)[column.id];\n if (value !== undefined && value !== null && value !== \"\") {\n uniqueValues.add(String(value));\n }\n });\n\n return {\n id: column.id,\n label: column.label,\n options: Array.from(uniqueValues).sort(),\n multiple: column.multiFilter,\n };\n });\n}\n\nfunction resolveFilterOptions<T>(\n columns: DataTableProps<T>[\"columns\"],\n data: T[],\n externalFilterOptions: FilterOption[] | undefined,\n asyncFilterOptions: AsyncFilterOptionsState,\n): FilterOption[] {\n if (!externalFilterOptions?.length) {\n return buildGeneratedFilterOptions(columns, data);\n }\n\n return externalFilterOptions.map((filter) => {\n const asyncState = asyncFilterOptions[filter.id];\n if (!asyncState) {\n return filter;\n }\n\n return {\n ...filter,\n options: asyncState.options,\n isLoading: asyncState.isLoading,\n };\n });\n}\n\nfunction matchesSearchQuery<T>(row: T, searchQuery: string): boolean {\n if (!searchQuery.trim()) {\n return true;\n }\n\n const query = searchQuery.toLowerCase();\n return Object.values(row as Record<string, unknown>).some((value) => {\n if (value === undefined || value === null) {\n return false;\n }\n\n return String(value).toLowerCase().includes(query);\n });\n}\n\nfunction matchesFilterValue(\n rowValue: unknown,\n filterValue: FilterValue,\n filterOption?: FilterOption,\n): boolean {\n if (isFilterValueEmpty(filterValue)) {\n return true;\n }\n\n switch (filterOption?.type) {\n case \"text\":\n return String(rowValue)\n .toLowerCase()\n .includes(String(filterValue).toLowerCase());\n case \"number-range\": {\n const rangeValue = getNumberRangeFilterValue(filterValue);\n const numericValue = Number(rowValue);\n if (rangeValue.min !== undefined && numericValue < rangeValue.min) {\n return false;\n }\n if (rangeValue.max !== undefined && numericValue > rangeValue.max) {\n return false;\n }\n return true;\n }\n case \"date-range\": {\n const rangeValue = getDateRangeFilterValue(filterValue);\n if (!rangeValue.start) {\n return true;\n }\n const timeValue = new Date(rowValue as string | number | Date).getTime();\n if (timeValue < rangeValue.start.getTime()) {\n return false;\n }\n return !rangeValue.end || timeValue <= rangeValue.end.getTime();\n }\n case \"date\": {\n const selectedDate = filterValue as Date;\n const rowDate = new Date(rowValue as string | number | Date);\n return selectedDate.toDateString() === rowDate.toDateString();\n }\n case \"switch\":\n case \"checkbox\":\n return Boolean(rowValue) === Boolean(filterValue);\n default: {\n const rowValueString = String(rowValue).toLowerCase();\n if (Array.isArray(filterValue)) {\n return filterValue.some(\n (value) => String(value).toLowerCase() === rowValueString,\n );\n }\n\n return typeof filterValue !== \"string\"\n ? true\n : rowValueString === filterValue.toLowerCase();\n }\n }\n}\n\nfunction filterClientData<T>(\n data: T[],\n activeFilters: FilterValues,\n searchQuery: string,\n serverSideFiltering: boolean,\n filterOptions: FilterOption[],\n): T[] {\n if (serverSideFiltering) {\n return data;\n }\n\n const filterOptionsMap = new Map(\n filterOptions.map((filterOption) => [filterOption.id, filterOption]),\n );\n\n return data.filter((row) => {\n if (!matchesSearchQuery(row, searchQuery)) {\n return false;\n }\n\n return Object.entries(activeFilters).every(([filterId, filterValue]) => {\n const rowValue = (row as Record<string, unknown>)[filterId];\n return matchesFilterValue(\n rowValue,\n filterValue,\n filterOptionsMap.get(filterId),\n );\n });\n });\n}\n\nfunction useAsyncFilterOptions(\n externalFilterOptions: FilterOption[] | undefined,\n filterSelectorOpen: boolean,\n): AsyncFilterOptionsState {\n const [asyncFilterOptions, setAsyncFilterOptions] =\n React.useState<AsyncFilterOptionsState>({});\n const asyncFilterOptionsRef = React.useRef(asyncFilterOptions);\n\n React.useEffect(() => {\n asyncFilterOptionsRef.current = asyncFilterOptions;\n }, [asyncFilterOptions]);\n\n const fetchAsyncOptions = React.useCallback(async (filter: FilterOption) => {\n if (\n !filter.fetchOptions ||\n asyncFilterOptionsRef.current[filter.id]?.options.length\n ) {\n return;\n }\n\n setAsyncFilterOptions((prev) => ({\n ...prev,\n [filter.id]: { options: [], isLoading: true },\n }));\n\n try {\n const options = await filter.fetchOptions();\n setAsyncFilterOptions((prev) => ({\n ...prev,\n [filter.id]: { options, isLoading: false },\n }));\n } catch {\n setAsyncFilterOptions((prev) => ({\n ...prev,\n [filter.id]: { options: [], isLoading: false },\n }));\n }\n }, []);\n\n React.useEffect(() => {\n if (!filterSelectorOpen || !externalFilterOptions) {\n return;\n }\n\n externalFilterOptions.forEach((filter) => {\n if (filter.fetchOptions) {\n void fetchAsyncOptions(filter);\n }\n });\n }, [externalFilterOptions, fetchAsyncOptions, filterSelectorOpen]);\n\n return asyncFilterOptions;\n}\n\nfunction LoadingFilterField({ label }: { label: string }) {\n return (\n <div className=\"h-10 flex items-center justify-center bg-neutral-100 dark:bg-neutral-800 rounded-md px-3\">\n <LoaderIcon\n className=\"w-4 h-4 animate-spin text-neutral-400\"\n aria-hidden=\"true\"\n />\n <span className=\"ml-2 text-sm text-neutral-500\">{label}</span>\n </div>\n );\n}\n\ninterface NumberRangeFilterProps {\n value: NumberRangeFilterValue;\n onChange: (value: NumberRangeFilterValue) => void;\n}\n\nfunction NumberRangeFilter({ value, onChange }: NumberRangeFilterProps) {\n return (\n <div className=\"flex items-center gap-1\">\n <Input\n type=\"number\"\n placeholder=\"Min\"\n value={value.min ?? \"\"}\n onChange={(event) => {\n const min =\n event.target.value === \"\" ? undefined : Number(event.target.value);\n onChange({ ...value, min });\n }}\n className=\"h-9 px-2 text-xs\"\n />\n <span className=\"text-neutral-400\">-</span>\n <Input\n type=\"number\"\n placeholder=\"Max\"\n value={value.max ?? \"\"}\n onChange={(event) => {\n const max =\n event.target.value === \"\" ? undefined : Number(event.target.value);\n onChange({ ...value, max });\n }}\n className=\"h-9 px-2 text-xs\"\n />\n </div>\n );\n}\n\ninterface FilterFieldControlProps {\n filter: FilterOption;\n value?: FilterValue;\n isActive: boolean;\n onChange: (value: FilterValue) => void;\n}\n\nfunction FilterFieldControl({\n filter,\n value,\n isActive,\n onChange,\n}: FilterFieldControlProps) {\n if (filter.isLoading) {\n return <LoadingFilterField label={filter.label} />;\n }\n\n const activeClassName = isActive ? \"border-accent\" : \"\";\n\n switch (filter.type) {\n case \"text\":\n return (\n <Input\n value={getStringFilterValue(value)}\n onChange={(event) => onChange(event.target.value)}\n placeholder={filter.placeholder || filter.label}\n className={activeClassName}\n />\n );\n case \"select\":\n return (\n <Select\n value={getStringFilterValue(value)}\n onChange={(event) => onChange(event.target.value)}\n placeholder={filter.placeholder || filter.label}\n options={toSelectOptions(filter.options)}\n className={activeClassName}\n />\n );\n case \"switch\":\n case \"checkbox\":\n return (\n <Switch\n checked={Boolean(value)}\n onChange={(event) => onChange(event.target.checked)}\n label={filter.label}\n />\n );\n case \"date\":\n return (\n <DatePicker\n mode=\"single\"\n value={getDateFilterValue(value)}\n onChange={(nextValue) => onChange(nextValue)}\n placeholder={filter.placeholder || filter.label}\n />\n );\n case \"date-range\":\n return (\n <DatePicker\n mode=\"range\"\n value={getDateRangeFilterValue(value)}\n onChange={(nextValue) => onChange(nextValue)}\n placeholder={filter.placeholder || filter.label}\n />\n );\n case \"number-range\":\n return (\n <NumberRangeFilter\n value={getNumberRangeFilterValue(value)}\n onChange={onChange}\n />\n );\n default:\n return filter.multiple ? (\n <MultiSelectCombobox\n value={getMultiStringFilterValue(value)}\n onChange={(values) => onChange(values)}\n placeholder={filter.placeholder || filter.label}\n options={toSelectOptions(filter.options)}\n className={isActive ? \"border-accent border-2\" : \"\"}\n />\n ) : (\n <Combobox\n value={getStringFilterValue(value)}\n onChange={(nextValue) => onChange(nextValue)}\n placeholder={filter.placeholder || filter.label}\n options={toSelectOptions(filter.options)}\n className={isActive ? \"border-accent border-2\" : \"\"}\n />\n );\n }\n}\n\ninterface ToolbarIconButtonProps {\n title: string;\n onClick?: () => void;\n disabled?: boolean;\n children: React.ReactNode;\n}\n\nfunction ToolbarIconButton({\n title,\n onClick,\n disabled,\n children,\n}: ToolbarIconButtonProps) {\n return (\n <Button\n onClick={onClick}\n disabled={disabled}\n title={title}\n aria-label={title}\n className={\n disabled\n ? `${DISABLED_ICON_BUTTON_CLASS_NAME} h-10 w-10 shrink-0 border-transparent bg-transparent px-0 py-0 text-base shadow-none hover:bg-transparent hover:opacity-100`\n : `${ICON_BUTTON_CLASS_NAME} h-10 w-10 shrink-0 border-transparent bg-transparent px-0 py-0 text-base shadow-none hover:opacity-100`\n }\n >\n {children}\n </Button>\n );\n}\n\ninterface SearchFieldProps {\n value: string;\n onChange: (value: string) => void;\n placeholder: string;\n}\n\nfunction SearchField({ value, onChange, placeholder }: SearchFieldProps) {\n return (\n <div className=\"relative w-[300px]\">\n <SearchIcon\n className={`pointer-events-none absolute left-4 top-1/2 z-10 -translate-y-1/2 text-neutral-400 ${TABLE_CONTROL_ICON_CLASS_NAME}`}\n aria-hidden=\"true\"\n />\n <Input\n type=\"text\"\n value={value}\n onChange={(event) => onChange(event.target.value)}\n placeholder={placeholder}\n style={{ paddingLeft: \"2.75rem\" }}\n />\n </div>\n );\n}\n\ninterface RowActionsCellProps<T> {\n rowIndex: number;\n row: T;\n isOpen: boolean;\n onToggle: (rowIndex: number) => void;\n onClose: () => void;\n onRowAction?: (action: string, row: T) => void;\n}\n\nfunction RowActionsCell<T>({\n rowIndex,\n row,\n isOpen,\n onToggle,\n onClose,\n onRowAction,\n}: RowActionsCellProps<T>) {\n return (\n <td className=\"px-2 py-3 text-right relative\">\n <Button\n onClick={() => onToggle(rowIndex)}\n aria-label=\"Open row actions\"\n className=\"h-8 w-8 border-none bg-transparent px-0 py-0 text-neutral-500 shadow-none hover:bg-neutral-100 hover:text-neutral-700 hover:opacity-100 dark:hover:bg-neutral-600 dark:hover:text-neutral-200\"\n >\n <EllipsisVerticalIcon\n className={TABLE_CONTROL_ICON_CLASS_NAME}\n aria-hidden=\"true\"\n />\n </Button>\n {isOpen ? (\n <>\n <div className=\"fixed inset-0 z-40\" onClick={onClose} />\n <div className=\"absolute right-0 top-full mt-1 bg-white dark:bg-neutral-800 rounded-lg shadow-lg border border-neutral-200 dark:border-neutral-700 z-50 min-w-32 py-1\">\n <Button\n onClick={() => {\n onRowAction?.(\"edit\", row);\n onClose();\n }}\n className=\"w-full justify-start rounded-none border-none bg-transparent px-4 py-2 text-sm font-normal text-neutral-700 shadow-none hover:bg-neutral-50 hover:text-neutral-900 hover:opacity-100 dark:text-neutral-200 dark:hover:bg-neutral-700 dark:hover:text-white\"\n >\n Edit\n </Button>\n <Button\n onClick={() => {\n onRowAction?.(\"delete\", row);\n onClose();\n }}\n className=\"w-full justify-start rounded-none border-none bg-transparent px-4 py-2 text-sm font-normal text-error shadow-none hover:bg-neutral-50 hover:text-error hover:opacity-100 dark:hover:bg-neutral-700\"\n >\n Delete\n </Button>\n </div>\n </>\n ) : null}\n </td>\n );\n}\n\ninterface DataTablePaginationProps<T> {\n table: Table<T>;\n totalCount?: number;\n filteredCount: number;\n}\n\nfunction DataTablePagination<T>({\n table,\n totalCount,\n filteredCount,\n}: DataTablePaginationProps<T>) {\n const { pageIndex, pageSize } = table.getState().pagination;\n const itemCount = totalCount ?? filteredCount;\n const pageStart = itemCount === 0 ? 0 : pageIndex * pageSize + 1;\n const pageEnd = Math.min((pageIndex + 1) * pageSize, itemCount);\n\n return (\n <div className=\"flex items-center justify-between px-4 py-3 border-t border-neutral-200 dark:border-neutral-700 bg-neutral-50 dark:bg-neutral-800/50\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm text-neutral-600 dark:text-neutral-400\">\n Showing {pageStart} to {pageEnd} of {itemCount} items\n </span>\n </div>\n\n <div className=\"flex flex-wrap items-center justify-end gap-2\">\n <span className=\"text-sm text-neutral-600 dark:text-neutral-400\">\n Rows\n </span>\n <Select\n value={String(pageSize)}\n onChange={(event) => table.setPageSize(Number(event.target.value))}\n aria-label=\"Rows per page\"\n containerClassName=\"w-24 min-w-24 shrink-0\"\n triggerClassName=\"px-3 font-medium text-neutral-900 dark:text-white\"\n options={[10, 20, 30, 50, 100].map((size) => ({\n value: String(size),\n label: String(size),\n }))}\n />\n\n <ToolbarIconButton\n title=\"First page\"\n onClick={() => table.setPageIndex(0)}\n disabled={!table.getCanPreviousPage()}\n >\n <ChevronsLeftIcon\n className={TABLE_CONTROL_ICON_CLASS_NAME}\n aria-hidden=\"true\"\n />\n </ToolbarIconButton>\n\n <ToolbarIconButton\n title=\"Previous page\"\n onClick={() => table.previousPage()}\n disabled={!table.getCanPreviousPage()}\n >\n <ChevronLeftIcon\n className={TABLE_CONTROL_ICON_CLASS_NAME}\n aria-hidden=\"true\"\n />\n </ToolbarIconButton>\n\n <span className=\"inline-flex h-10 shrink-0 items-center rounded-lg px-3 text-sm font-medium text-neutral-700 dark:text-neutral-300\">\n Page {pageIndex + 1} of {table.getPageCount()}\n </span>\n\n <ToolbarIconButton\n title=\"Next page\"\n onClick={() => table.nextPage()}\n disabled={!table.getCanNextPage()}\n >\n <ChevronRightIcon\n className={TABLE_CONTROL_ICON_CLASS_NAME}\n aria-hidden=\"true\"\n />\n </ToolbarIconButton>\n\n <ToolbarIconButton\n title=\"Last page\"\n onClick={() => table.setPageIndex(table.getPageCount() - 1)}\n disabled={!table.getCanNextPage()}\n >\n <ChevronsRightIcon\n className={TABLE_CONTROL_ICON_CLASS_NAME}\n aria-hidden=\"true\"\n />\n </ToolbarIconButton>\n </div>\n </div>\n );\n}\n\ninterface FilterSelectorMenuProps {\n filterOptions: FilterOption[];\n visibleFilters: string[];\n onToggleFilter: (filterId: string, isVisible: boolean) => void;\n onShowAll: () => void;\n onHideAll: () => void;\n}\n\nfunction FilterSelectorMenu({\n filterOptions,\n visibleFilters,\n onToggleFilter,\n onShowAll,\n onHideAll,\n}: FilterSelectorMenuProps) {\n return (\n <div className=\"p-2 min-w-48 space-y-1\">\n <div className=\"px-2 pb-2 text-xs font-semibold text-neutral-500 dark:text-neutral-300\">\n Show filters\n </div>\n {filterOptions.map((filter) => (\n <div key={filter.id} className=\"min-w-36\">\n <Checkbox\n checked={visibleFilters.includes(filter.id)}\n onChange={(event) =>\n onToggleFilter(filter.id, event.target.checked)\n }\n label={filter.label}\n />\n </div>\n ))}\n <div className=\"flex gap-2 border-t border-neutral-200 pt-2 dark:border-neutral-700\">\n <Button\n onClick={onShowAll}\n size=\"small\"\n className=\"flex-1 border-none bg-transparent px-1 py-1 text-xs font-semibold text-accent shadow-none hover:bg-transparent hover:text-accent-hover hover:opacity-100\"\n >\n SHOW ALL\n </Button>\n <Button\n onClick={onHideAll}\n size=\"small\"\n className=\"flex-1 border-none bg-transparent px-1 py-1 text-xs font-semibold text-neutral-500 shadow-none hover:bg-transparent hover:text-neutral-600 hover:opacity-100 dark:text-neutral-300 dark:hover:text-white\"\n >\n HIDE ALL\n </Button>\n </div>\n </div>\n );\n}\n\ninterface DataTableToolbarProps<T> {\n searchQuery: string;\n onSearchChange: (value: string) => void;\n searchPlaceholder: string;\n bulkDeleteEnabled: boolean;\n bulkSelectionActive: boolean;\n selectedCount: number;\n bulkActionsContent?: React.ReactNode;\n bulkActionCard?: React.ReactNode;\n onToggleBulkSelection: () => void;\n onBulkDeleteSelected: () => void;\n onExport?: () => void;\n columnMenuOpen: boolean;\n onToggleColumnMenu: () => void;\n onCloseColumnMenu: () => void;\n columns: DataTableProps<T>[\"columns\"];\n onColumnToggle?: (columnId: string) => void;\n onShowAllColumns: () => void;\n onHideAllColumns: () => void;\n}\n\nfunction DataTableToolbar<T>({\n searchQuery,\n onSearchChange,\n searchPlaceholder,\n bulkDeleteEnabled,\n bulkSelectionActive,\n selectedCount,\n bulkActionsContent,\n bulkActionCard,\n onToggleBulkSelection,\n onBulkDeleteSelected,\n onExport,\n columnMenuOpen,\n onToggleColumnMenu,\n onCloseColumnMenu,\n columns,\n onColumnToggle,\n onShowAllColumns,\n onHideAllColumns,\n}: DataTableToolbarProps<T>) {\n const hasSelectedRows = selectedCount > 0;\n\n return (\n <div className=\"border-b border-neutral-200 px-4 py-3 dark:border-neutral-700\">\n <div className=\"flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between\">\n <div className=\"flex min-w-0 flex-1 flex-wrap items-center gap-2\">\n {bulkDeleteEnabled ? (\n <FilterButton\n icon={\n <SelectionIcon\n className={TABLE_COMPLEX_ICON_CLASS_NAME}\n aria-hidden=\"true\"\n />\n }\n label={\n bulkSelectionActive\n ? \"Disable bulk selection\"\n : \"Enable bulk selection\"\n }\n onClick={onToggleBulkSelection}\n hasActive={bulkSelectionActive}\n />\n ) : null}\n\n <SearchField\n value={searchQuery}\n onChange={onSearchChange}\n placeholder={searchPlaceholder}\n />\n </div>\n\n <div className=\"flex items-center gap-1 self-end lg:self-auto\">\n <ToolbarIconButton onClick={onExport} title=\"Refresh\">\n <RefreshIcon\n className={TABLE_CONTROL_ICON_CLASS_NAME}\n aria-hidden=\"true\"\n />\n </ToolbarIconButton>\n\n <div className=\"relative\">\n <ToolbarIconButton\n onClick={onToggleColumnMenu}\n title=\"Column settings\"\n >\n <SettingsIcon\n className={TABLE_COMPLEX_ICON_CLASS_NAME}\n aria-hidden=\"true\"\n />\n </ToolbarIconButton>\n\n <FilterDropdown isOpen={columnMenuOpen} onClose={onCloseColumnMenu}>\n <ColumnToggle\n columns={columns}\n onToggle={(columnId) => {\n onColumnToggle?.(columnId);\n }}\n onShowAll={onShowAllColumns}\n onHideAll={onHideAllColumns}\n />\n </FilterDropdown>\n </div>\n </div>\n </div>\n\n {bulkSelectionActive && hasSelectedRows\n ? (bulkActionCard ?? (\n <div className=\"mt-2 flex flex-col gap-2 rounded-[4px] border border-neutral-200 bg-neutral-50 px-3 py-2 shadow-sm dark:border-neutral-700 dark:bg-neutral-800/50 dark:shadow-black/25 lg:flex-row lg:items-center lg:justify-between\">\n <div className=\"flex min-w-0 flex-wrap items-center gap-2\">\n <Chip\n variant=\"soft\"\n color=\"primary\"\n size=\"sm\"\n className=\"uppercase tracking-wide\"\n >\n Bulk actions\n </Chip>\n <p className=\"text-sm font-medium text-neutral-900 dark:text-white\">\n {selectedCount} {selectedCount === 1 ? \"row\" : \"rows\"}{\" \"}\n selected\n </p>\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2\">\n {bulkActionsContent}\n {bulkDeleteEnabled ? (\n <Button\n onClick={onBulkDeleteSelected}\n primary\n size=\"small\"\n className=\"border-accent/20 px-3 py-2 text-sm text-on-accent shadow-lg shadow-accent/20 hover:bg-accent-hover hover:opacity-100\"\n >\n <TrashIcon className=\"h-4 w-4\" aria-hidden=\"true\" />\n Delete selected\n </Button>\n ) : null}\n </div>\n </div>\n ))\n : null}\n </div>\n );\n}\n\ninterface TableStateRowProps {\n colSpan: number;\n children: React.ReactNode;\n}\n\nfunction TableStateRow({ colSpan, children }: TableStateRowProps) {\n return (\n <tr>\n <td colSpan={colSpan} className=\"px-4 py-12 text-center text-neutral-500\">\n {children}\n </td>\n </tr>\n );\n}\n\nfunction LoadingTableState({ colSpan }: { colSpan: number }) {\n return (\n <TableStateRow colSpan={colSpan}>\n <div className=\"flex flex-col items-center gap-3\">\n <LoaderIcon\n className=\"w-8 h-8 animate-spin text-accent\"\n aria-hidden=\"true\"\n />\n <span>Loading data...</span>\n </div>\n </TableStateRow>\n );\n}\n\nfunction EmptyTableState({ colSpan }: { colSpan: number }) {\n return (\n <TableStateRow colSpan={colSpan}>\n <div className=\"flex flex-col items-center gap-2\">\n <span className=\"text-4xl\">🔍</span>\n <p className=\"font-medium\">No results found</p>\n <p className=\"text-sm\">Try adjusting the filter</p>\n </div>\n </TableStateRow>\n );\n}\n\ninterface DataTableRowsProps<T> {\n table: Table<T>;\n isLoading: boolean;\n bulkSelectionActive: boolean;\n selectedRowIds: Record<string, boolean>;\n onToggleRowSelection: (rowId: string, checked: boolean) => void;\n rowMenuOpen: number | null;\n onToggleRowMenu: (rowIndex: number) => void;\n onCloseRowMenu: () => void;\n onRowAction?: (action: string, row: T) => void;\n}\n\nfunction DataTableRows<T>({\n table,\n isLoading,\n bulkSelectionActive,\n selectedRowIds,\n onToggleRowSelection,\n rowMenuOpen,\n onToggleRowMenu,\n onCloseRowMenu,\n onRowAction,\n}: DataTableRowsProps<T>) {\n const colSpan =\n table.getVisibleLeafColumns().length + (bulkSelectionActive ? 2 : 1);\n\n if (isLoading) {\n return <LoadingTableState colSpan={colSpan} />;\n }\n\n if (table.getRowModel().rows.length === 0) {\n return <EmptyTableState colSpan={colSpan} />;\n }\n\n return (\n <>\n {table.getRowModel().rows.map((row) => (\n <tr\n key={row.id}\n className=\"border-b border-neutral-100 dark:border-neutral-700 hover:bg-neutral-50 dark:hover:bg-neutral-700/50 transition-colors\"\n >\n {bulkSelectionActive ? (\n <td className=\"w-12 px-4 py-3 align-middle\">\n <Checkbox\n aria-label={`Select row ${row.id}`}\n checked={Boolean(selectedRowIds[row.id])}\n onChange={(event) =>\n onToggleRowSelection(row.id, event.target.checked)\n }\n />\n </td>\n ) : null}\n {row.getVisibleCells().map((cell) => (\n <td\n key={cell.id}\n className=\"px-4 py-3 text-sm text-neutral-700 dark:text-neutral-300\"\n >\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </td>\n ))}\n <RowActionsCell\n rowIndex={row.index}\n row={row.original}\n isOpen={rowMenuOpen === row.index}\n onToggle={onToggleRowMenu}\n onClose={onCloseRowMenu}\n onRowAction={onRowAction}\n />\n </tr>\n ))}\n </>\n );\n}\n\nconst usesManualPagination = (\n totalCount?: number,\n onPaginationChange?: (pageIndex: number, pageSize: number) => void,\n) => totalCount !== undefined || typeof onPaginationChange === \"function\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport default function DataTable<T = Record<string, any>>({\n columns,\n data,\n isLoading = false,\n onColumnToggle,\n pageSize = 10,\n maxHeight = \"500px\",\n onSearch,\n onExport,\n onRowAction,\n onBulkDelete,\n renderBulkActions,\n renderBulkActionCard,\n onFilterChange,\n onFiltersApply,\n serverSideFiltering = false,\n filterOptions: externalFilterOptions,\n searchPlaceholder = \"Search ...\",\n totalCount,\n onPaginationChange,\n}: DataTableProps<T>) {\n const [pagination, setPagination] = React.useState<PaginationState>({\n pageIndex: 0,\n pageSize: pageSize,\n });\n const [columnMenuOpen, setColumnMenuOpen] = React.useState(false);\n const [profileMenuOpen, setProfileMenuOpen] = React.useState(false);\n const [profileOpen, setProfileOpen] = React.useState(false);\n const [filterSelectorOpen, setFilterSelectorOpen] = React.useState(false);\n const [visibleFilters, setVisibleFilters] = React.useState<string[]>([]);\n const [activeFilters, setActiveFilters] = React.useState<FilterValues>({});\n const [bulkSelectionActive, setBulkSelectionActive] = React.useState(false);\n const [selectedRowIds, setSelectedRowIds] = React.useState<\n Record<string, boolean>\n >({});\n const [rowMenuOpen, setRowMenuOpen] = React.useState<number | null>(null);\n const [searchQuery, setSearchQuery] = React.useState(\"\");\n const [columnVisibility, setColumnVisibility] = React.useState<\n Record<string, boolean>\n >(() =>\n Object.fromEntries(\n columns.map((column) => [column.id, column.visible !== false]),\n ),\n );\n\n const columnsVisibilitySignature = React.useMemo(\n () =>\n columns\n .map((column) => `${column.id}:${column.visible !== false}`)\n .join(\"|\"),\n [columns],\n );\n\n React.useEffect(() => {\n setColumnVisibility(\n Object.fromEntries(\n columns.map((column) => [column.id, column.visible !== false]),\n ),\n );\n }, [columns, columnsVisibilitySignature]);\n\n const asyncFilterOptions = useAsyncFilterOptions(\n externalFilterOptions,\n filterSelectorOpen,\n );\n\n // Auto-generate filter options from columns that are filterable\n const filterOptions: FilterOption[] = React.useMemo(() => {\n return resolveFilterOptions(\n columns,\n data,\n externalFilterOptions,\n asyncFilterOptions,\n );\n }, [columns, data, externalFilterOptions, asyncFilterOptions]);\n\n const resolvedColumns = React.useMemo(\n () =>\n columns.map((column) => ({\n ...column,\n visible: columnVisibility[column.id] ?? column.visible !== false,\n })),\n [columnVisibility, columns],\n );\n\n const visibleColumns = React.useMemo(\n () => resolvedColumns.filter((column) => column.visible !== false),\n [resolvedColumns],\n );\n const manualPagination = usesManualPagination(totalCount, onPaginationChange);\n const pageCount =\n totalCount === undefined\n ? undefined\n : Math.ceil(totalCount / pagination.pageSize);\n\n // Filter data based on search query and active filters (client-side only)\n const filteredData = React.useMemo(() => {\n return filterClientData(\n data,\n activeFilters,\n searchQuery,\n serverSideFiltering,\n filterOptions,\n );\n }, [data, activeFilters, searchQuery, serverSideFiltering, filterOptions]);\n\n // TanStack Table columns definition\n const tableColumns = React.useMemo<ColumnDef<T>[]>(\n () =>\n visibleColumns.map((col) => ({\n id: col.id,\n accessorKey: col.id,\n header: col.label,\n cell: (info: CellContext<T, unknown>) => {\n const value = info.getValue();\n\n if (col.renderCell) {\n return col.renderCell({\n value,\n row: info.row.original,\n rowIndex: info.row.index,\n columnId: col.id,\n });\n }\n\n return renderDefaultCellValue(value);\n },\n })),\n [visibleColumns],\n );\n\n const updatePagination = React.useCallback(\n (\n updater:\n | PaginationState\n | ((previous: PaginationState) => PaginationState),\n ) => {\n setPagination((previous) => {\n const nextPagination =\n typeof updater === \"function\" ? updater(previous) : updater;\n\n if (\n previous.pageIndex !== nextPagination.pageIndex ||\n previous.pageSize !== nextPagination.pageSize\n ) {\n onPaginationChange?.(\n nextPagination.pageIndex,\n nextPagination.pageSize,\n );\n }\n\n return nextPagination;\n });\n },\n [onPaginationChange],\n );\n\n const table = useReactTable({\n data: filteredData,\n columns: tableColumns,\n getCoreRowModel: getCoreRowModel(),\n getPaginationRowModel: getPaginationRowModel(),\n getFilteredRowModel: getFilteredRowModel(),\n state: {\n pagination,\n globalFilter: searchQuery,\n },\n onPaginationChange: updatePagination,\n manualPagination,\n pageCount,\n });\n\n const visibleRows = table.getRowModel().rows;\n const bulkDeleteEnabled = typeof onBulkDelete === \"function\";\n const selectedRows = React.useMemo(\n () =>\n visibleRows\n .filter((row) => selectedRowIds[row.id])\n .map((row) => row.original),\n [selectedRowIds, visibleRows],\n );\n const allVisibleRowsSelected =\n visibleRows.length > 0 &&\n visibleRows.every((row) => selectedRowIds[row.id]);\n\n React.useEffect(() => {\n updatePagination((previous) =>\n previous.pageIndex === 0 ? previous : { ...previous, pageIndex: 0 },\n );\n }, [activeFilters, searchQuery, updatePagination]);\n\n React.useEffect(() => {\n setSelectedRowIds((previous) => {\n const visibleRowIds = new Set(visibleRows.map((row) => row.id));\n const nextSelection = Object.fromEntries(\n Object.entries(previous).filter(\n ([rowId, isSelected]) => isSelected && visibleRowIds.has(rowId),\n ),\n );\n\n const previousKeys = Object.keys(previous).sort().join(\"|\");\n const nextKeys = Object.keys(nextSelection).sort().join(\"|\");\n\n return previousKeys === nextKeys ? previous : nextSelection;\n });\n }, [visibleRows]);\n\n const applyFilters = React.useCallback(\n (nextFilters: FilterValues) => {\n setActiveFilters(nextFilters);\n onFilterChange?.(nextFilters);\n\n if (serverSideFiltering) {\n onFiltersApply?.(nextFilters);\n }\n },\n [onFilterChange, onFiltersApply, serverSideFiltering],\n );\n\n const handleSearchChange = React.useCallback(\n (value: string) => {\n setSearchQuery(value);\n onSearch?.(value);\n },\n [onSearch],\n );\n\n const handleFilterChange = React.useCallback(\n (filterId: string, value: FilterValue) => {\n applyFilters({\n ...activeFilters,\n [filterId]: value,\n });\n },\n [activeFilters, applyFilters],\n );\n\n const handleResetFilters = React.useCallback(() => {\n applyFilters({});\n }, [applyFilters]);\n\n const handleToggleFilterVisibility = React.useCallback(\n (filterId: string, isVisible: boolean) => {\n setVisibleFilters((previous) => {\n if (isVisible) {\n return previous.includes(filterId)\n ? previous\n : [...previous, filterId];\n }\n\n return previous.filter((id) => id !== filterId);\n });\n\n if (!isVisible && filterId in activeFilters) {\n const nextFilters = { ...activeFilters };\n delete nextFilters[filterId];\n applyFilters(nextFilters);\n }\n },\n [activeFilters, applyFilters],\n );\n\n const handleShowAllFilters = React.useCallback(() => {\n setVisibleFilters(filterOptions.map((filter) => filter.id));\n }, [filterOptions]);\n\n const handleHideAllFilters = React.useCallback(() => {\n setVisibleFilters([]);\n handleResetFilters();\n }, [handleResetFilters]);\n\n const handleToggleRowMenu = React.useCallback((rowIndex: number) => {\n setRowMenuOpen((previous) => (previous === rowIndex ? null : rowIndex));\n }, []);\n\n const handleToggleFilterSelector = React.useCallback(() => {\n setFilterSelectorOpen((previous) => !previous);\n }, []);\n\n const handleToggleProfileMenu = React.useCallback(() => {\n setProfileMenuOpen((previous) => !previous);\n }, []);\n\n const handleToggleColumnMenu = React.useCallback(() => {\n setColumnMenuOpen((previous) => !previous);\n }, []);\n\n const handleToggleColumnVisibility = React.useCallback(\n (columnId: string) => {\n setColumnVisibility((previous) => ({\n ...previous,\n [columnId]: !(previous[columnId] ?? true),\n }));\n onColumnToggle?.(columnId);\n },\n [onColumnToggle],\n );\n\n const handleShowAllColumns = React.useCallback(() => {\n setColumnVisibility(\n Object.fromEntries(columns.map((column) => [column.id, true])),\n );\n }, [columns]);\n\n const handleHideAllColumns = React.useCallback(() => {\n setColumnVisibility(\n Object.fromEntries(columns.map((column) => [column.id, false])),\n );\n }, [columns]);\n\n const handleToggleBulkSelection = React.useCallback(() => {\n setBulkSelectionActive((previous) => {\n if (previous) {\n setSelectedRowIds({});\n }\n\n return !previous;\n });\n }, []);\n\n const handleToggleRowSelection = React.useCallback(\n (rowId: string, checked: boolean) => {\n setSelectedRowIds((previous) => {\n if (checked) {\n return {\n ...previous,\n [rowId]: true,\n };\n }\n\n const nextSelection = { ...previous };\n delete nextSelection[rowId];\n return nextSelection;\n });\n },\n [],\n );\n\n const handleToggleAllVisibleRows = React.useCallback(\n (checked: boolean) => {\n setSelectedRowIds((previous) => {\n const nextSelection = { ...previous };\n\n visibleRows.forEach((row) => {\n if (checked) {\n nextSelection[row.id] = true;\n } else {\n delete nextSelection[row.id];\n }\n });\n\n return nextSelection;\n });\n },\n [visibleRows],\n );\n\n const handleBulkDeleteSelected = React.useCallback(() => {\n if (!onBulkDelete || selectedRows.length === 0) {\n return;\n }\n\n onBulkDelete(selectedRows);\n setSelectedRowIds({});\n }, [onBulkDelete, selectedRows]);\n\n const handleClearSelectedRows = React.useCallback(() => {\n setSelectedRowIds({});\n }, []);\n\n const handleDisableBulkSelection = React.useCallback(() => {\n setBulkSelectionActive(false);\n setSelectedRowIds({});\n }, []);\n\n const bulkActionContext = React.useMemo<DataTableBulkActionContext<T>>(\n () => ({\n selectedRows,\n selectedCount: selectedRows.length,\n clearSelection: handleClearSelectedRows,\n disableBulkSelection: handleDisableBulkSelection,\n }),\n [handleClearSelectedRows, handleDisableBulkSelection, selectedRows],\n );\n\n const bulkActionsContent = renderBulkActions?.(bulkActionContext);\n const bulkActionCard = renderBulkActionCard?.(bulkActionContext);\n\n const handleOpenProfile = React.useCallback(() => {\n setProfileOpen(true);\n setProfileMenuOpen(false);\n }, []);\n\n const hasActiveFilters = Object.values(activeFilters).some(isFilterActive);\n\n const handleSaveProfile = (profileName: string) => {\n void {\n name: profileName,\n filters: activeFilters,\n timestamp: new Date().toISOString(),\n };\n };\n\n return (\n <div className=\"space-y-0\">\n {/* Row 1: Filters Row - Separated with border */}\n <div className=\"mb-4 flex items-center justify-between gap-4 rounded-[8px] border border-neutral-200 bg-neutral-50 px-4 py-4 dark:border-neutral-700 dark:bg-neutral-800/50\">\n <div className=\"flex items-center gap-3 flex-wrap\">\n {filterOptions\n .filter((filter) => visibleFilters.includes(filter.id))\n .map((filter, index) => {\n const isActive = isFilterActive(activeFilters[filter.id]);\n\n return (\n <div\n key={filter.id}\n className={`min-w-[200px] ${\n index > 0\n ? \"border-l border-neutral-200 pl-3 dark:border-neutral-600\"\n : \"\"\n }`}\n >\n <FilterFieldControl\n filter={filter}\n value={activeFilters[filter.id]}\n isActive={isActive}\n onChange={(value) => handleFilterChange(filter.id, value)}\n />\n </div>\n );\n })}\n </div>\n\n {/* Right side icons */}\n <div className=\"flex items-center gap-1 ml-auto\">\n <div className=\"relative\">\n <ToolbarIconButton\n onClick={handleToggleFilterSelector}\n title=\"Add filter\"\n >\n <FilterIcon\n className={TABLE_COMPLEX_ICON_CLASS_NAME}\n aria-hidden=\"true\"\n />\n </ToolbarIconButton>\n <FilterDropdown\n isOpen={filterSelectorOpen}\n onClose={() => setFilterSelectorOpen(false)}\n >\n <FilterSelectorMenu\n filterOptions={filterOptions}\n visibleFilters={visibleFilters}\n onToggleFilter={handleToggleFilterVisibility}\n onShowAll={handleShowAllFilters}\n onHideAll={handleHideAllFilters}\n />\n </FilterDropdown>\n </div>\n\n <ToolbarIconButton\n onClick={handleResetFilters}\n disabled={!hasActiveFilters}\n title=\"Clear filters\"\n >\n <FilterXIcon\n className={TABLE_COMPLEX_ICON_CLASS_NAME}\n aria-hidden=\"true\"\n />\n </ToolbarIconButton>\n\n <div className=\"relative\">\n <ToolbarIconButton\n onClick={handleToggleProfileMenu}\n title=\"Filter profiles\"\n >\n <FilterProfileIcon\n className={TABLE_COMPLEX_ICON_CLASS_NAME}\n aria-hidden=\"true\"\n />\n </ToolbarIconButton>\n <FilterDropdown\n isOpen={profileMenuOpen}\n onClose={() => setProfileMenuOpen(false)}\n >\n <div className=\"p-2 min-w-48\">\n <Button\n onClick={handleOpenProfile}\n className=\"w-full justify-start border-2 border-dashed border-accent/40 bg-transparent px-4 py-3 text-left text-sm font-medium text-accent shadow-none hover:bg-accent-subtle hover:opacity-100\"\n >\n Save new filter profile\n </Button>\n </div>\n </FilterDropdown>\n </div>\n </div>\n </div>\n\n {/* Table */}\n <div className=\"bg-background-secondary rounded-lg border border-neutral-200 dark:border-neutral-700 overflow-hidden\">\n <DataTableToolbar\n searchQuery={searchQuery}\n onSearchChange={handleSearchChange}\n searchPlaceholder={searchPlaceholder}\n bulkDeleteEnabled={bulkDeleteEnabled}\n bulkSelectionActive={bulkSelectionActive}\n selectedCount={selectedRows.length}\n bulkActionsContent={bulkActionsContent}\n bulkActionCard={bulkActionCard}\n onToggleBulkSelection={handleToggleBulkSelection}\n onBulkDeleteSelected={handleBulkDeleteSelected}\n onExport={onExport}\n columnMenuOpen={columnMenuOpen}\n onToggleColumnMenu={handleToggleColumnMenu}\n onCloseColumnMenu={() => setColumnMenuOpen(false)}\n columns={resolvedColumns}\n onColumnToggle={handleToggleColumnVisibility}\n onShowAllColumns={handleShowAllColumns}\n onHideAllColumns={handleHideAllColumns}\n />\n\n {/* Table Container */}\n <div className=\"overflow-auto\" style={{ maxHeight }}>\n <table className=\"w-full min-w-[600px]\">\n <thead className=\"sticky top-0 z-10 bg-background-secondary\">\n {table.getHeaderGroups().map((headerGroup) => (\n <tr\n key={headerGroup.id}\n className=\"border-b border-neutral-200 dark:border-neutral-700\"\n >\n {bulkSelectionActive ? (\n <th className=\"w-12 px-4 py-3 bg-background-secondary\">\n <Checkbox\n aria-label=\"Select all visible rows\"\n checked={allVisibleRowsSelected}\n onChange={(event) =>\n handleToggleAllVisibleRows(event.target.checked)\n }\n />\n </th>\n ) : null}\n {headerGroup.headers.map((header) => (\n <th\n key={header.id}\n className=\"bg-background-secondary px-4 py-3 text-left text-sm font-semibold text-neutral-900 dark:text-white whitespace-nowrap\"\n >\n {header.isPlaceholder\n ? null\n : flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )}\n </th>\n ))}\n <th className=\"w-12 bg-background-secondary\"></th>\n </tr>\n ))}\n </thead>\n <tbody>\n <DataTableRows\n table={table}\n isLoading={isLoading}\n bulkSelectionActive={bulkSelectionActive}\n selectedRowIds={selectedRowIds}\n onToggleRowSelection={handleToggleRowSelection}\n rowMenuOpen={rowMenuOpen}\n onToggleRowMenu={handleToggleRowMenu}\n onCloseRowMenu={() => setRowMenuOpen(null)}\n onRowAction={onRowAction}\n />\n </tbody>\n </table>\n </div>\n\n <DataTablePagination\n table={table}\n totalCount={totalCount}\n filteredCount={filteredData.length}\n />\n </div>\n\n {/* Profile Modal */}\n <FilterProfile\n isOpen={profileOpen}\n onClose={() => setProfileOpen(false)}\n onSaveProfile={(name) => {\n handleSaveProfile(name);\n setProfileOpen(false);\n }}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"data-table-W1sK5tkL.cjs","names":[],"sources":["../../src/components/data-display/data-table/DataTable.tsx"],"sourcesContent":["import React from \"react\";\nimport {\n useReactTable,\n getCoreRowModel,\n getPaginationRowModel,\n getFilteredRowModel,\n flexRender,\n type CellContext,\n type ColumnDef,\n type PaginationState,\n type Table,\n} from \"@tanstack/react-table\";\nimport { Chip } from \"../chip\";\nimport { Button } from \"../../forms/button\";\nimport { Combobox } from \"../../forms/combobox\";\nimport { MultiSelectCombobox } from \"../../forms/multi-select-combobox\";\nimport { Checkbox } from \"../../forms/checkbox\";\nimport { Input } from \"../../forms/input\";\nimport { Select } from \"../../forms/select\";\nimport { Switch } from \"../../forms/switch\";\nimport {\n DatePicker,\n type DatePickerValue,\n type DateRangeValue,\n} from \"../../forms/date-picker\";\nimport {\n ChevronLeftIcon,\n ChevronRightIcon,\n ChevronsLeftIcon,\n ChevronsRightIcon,\n EllipsisVerticalIcon,\n FilterIcon,\n FilterProfileIcon,\n FilterXIcon,\n LoaderIcon,\n RefreshIcon,\n SearchIcon,\n SelectionIcon,\n SettingsIcon,\n TrashIcon,\n} from \"../../icons\";\n\n// Filter option type - can be static or async\nexport interface FilterOption {\n id: string;\n label: string;\n type?:\n | \"text\"\n | \"select\"\n | \"combobox\"\n | \"checkbox\"\n | \"switch\"\n | \"date\"\n | \"date-range\"\n | \"number-range\";\n placeholder?: string;\n options?: string[]; // Static options\n // Async options support\n queryKey?: string | string[]; // React Query key for caching\n fetchOptions?: () => Promise<string[]>; // Async function to fetch options\n isLoading?: boolean; // Loading state (managed externally)\n multiple?: boolean; // Enable multi-select\n /* Crystal UI Unification */\n /*\n ### Automated Browser Testing\n The filters were verified using the browser subagent, confirming that each filter type correctly updates the table data in real-time and adheres to our new unified \"Crystal\" aesthetic.\n\n ````carousel\n \n <!-- slide -->\n \n <!-- slide -->\n \n ````\n\n ### Key Successes:\n - **Unified Aesthetic**: All components now share a consistent `backdrop-blur-xl` and semi-transparent background.\n - **Improved Visual Hierarchy**: The crystal effect makes the components feel integrated with the page while still being clearly interactive.\n - **Robust Logic**: Maintained all advanced filtering logic (date ranges, numeric ranges, partial matches) while upgrading the visual layer.\n */\n}\n\n// Filter value can be single string, array of strings, or range objects\nexport type FilterValue =\n | string\n | string[]\n | boolean\n | DatePickerValue\n | { min?: number; max?: number };\nexport type FilterValues = Record<string, FilterValue>;\n\nexport interface DataTableBulkActionContext<T> {\n selectedRows: T[];\n selectedCount: number;\n clearSelection: () => void;\n disableBulkSelection: () => void;\n}\n\nexport interface DataTableCellRenderContext<T> {\n value: unknown;\n row: T;\n rowIndex: number;\n columnId: string;\n}\n\nexport interface DataTableColumn<T> {\n id: string;\n label: string;\n visible?: boolean;\n filterable?: boolean;\n multiFilter?: boolean;\n priority?: number;\n renderCell?: (context: DataTableCellRenderContext<T>) => React.ReactNode;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface DataTableProps<T = Record<string, any>> {\n columns: DataTableColumn<T>[];\n data: T[];\n isLoading?: boolean; // Table data loading state\n onColumnToggle?: (columnId: string) => void;\n /** Number of items per page */\n pageSize?: number;\n /** Maximum height for the scrollable table area */\n maxHeight?: string;\n onSearch?: (query: string) => void;\n onExport?: () => void;\n onRowAction?: (action: string, row: T) => void;\n onBulkDelete?: (rows: T[]) => void;\n renderBulkActions?: (\n context: DataTableBulkActionContext<T>,\n ) => React.ReactNode;\n renderBulkActionCard?: (\n context: DataTableBulkActionContext<T>,\n ) => React.ReactNode;\n onFilterChange?: (filters: FilterValues) => void;\n // Filter options - can include async filters\n filterOptions?: FilterOption[];\n // Called when filters are applied (for server-side filtering)\n onFiltersApply?: (filters: FilterValues) => void;\n // Enable server-side filtering mode\n serverSideFiltering?: boolean;\n searchPlaceholder?: string;\n children?: React.ReactNode;\n /** Total row count for server-side pagination */\n totalCount?: number;\n /** Callback when pagination changes (for server-side pagination) */\n onPaginationChange?: (pageIndex: number, pageSize: number) => void;\n}\n\nfunction renderDefaultCellValue(value: unknown): React.ReactNode {\n if (value === undefined || value === null || value === \"\") {\n return \"-\";\n }\n\n if (typeof value === \"boolean\") {\n return value ? \"Yes\" : \"No\";\n }\n\n if (Array.isArray(value)) {\n return value.length > 0 ? value.join(\", \") : \"-\";\n }\n\n return value as React.ReactNode;\n}\n\ninterface FilterDropdownProps {\n isOpen: boolean;\n onClose: () => void;\n children: React.ReactNode;\n}\n\nexport const FilterDropdown: React.FC<FilterDropdownProps> = ({\n isOpen,\n onClose,\n children,\n}) => {\n if (!isOpen) return null;\n\n return (\n <>\n <div\n className=\"fixed inset-0 z-40\"\n onClick={onClose}\n aria-hidden=\"true\"\n />\n <div className=\"absolute top-full right-0 z-50 mt-2 min-w-64 overflow-hidden rounded-[4px] border border-white/45 bg-neutral-50 shadow-[0_18px_40px_rgba(15,23,42,0.18)] ring-1 ring-inset ring-white/35 backdrop-blur-2xl dark:border-white/10 dark:bg-neutral-800/50 dark:shadow-[0_22px_48px_rgba(0,0,0,0.42)] dark:ring-white/6\">\n {children}\n </div>\n </>\n );\n};\n\ninterface FilterButtonProps {\n icon: React.ReactNode;\n label: string;\n onClick: () => void;\n hasActive?: boolean;\n}\n\nexport const FilterButton: React.FC<FilterButtonProps> = ({\n icon,\n label,\n onClick,\n hasActive,\n}) => (\n <Button\n onClick={onClick}\n title={label}\n aria-label={label}\n className={`h-10 min-w-10 px-0 py-0 shadow-none ${\n hasActive\n ? \"border-accent/20 bg-accent-subtle text-accent hover:bg-accent-subtle hover:opacity-100\"\n : \"border-transparent bg-transparent text-neutral-600 hover:bg-neutral-100 hover:text-neutral-700 hover:opacity-100 dark:text-neutral-400 dark:hover:bg-neutral-700 dark:hover:text-neutral-200\"\n }`}\n >\n {icon}\n </Button>\n);\n\ninterface ColumnToggleProps {\n columns: {\n id: string;\n label: string;\n visible?: boolean;\n }[];\n onToggle: (columnId: string) => void;\n onShowAll?: () => void;\n onHideAll?: () => void;\n}\n\nexport const ColumnToggle: React.FC<ColumnToggleProps> = ({\n columns,\n onToggle,\n onShowAll,\n onHideAll,\n}) => (\n <div className=\"p-4 space-y-3\">\n <div className=\"flex items-center justify-between mb-3\">\n <span className=\"text-sm font-semibold text-neutral-900 dark:text-white\">\n COLUMNS\n </span>\n </div>\n\n <div className=\"space-y-2 max-h-64 overflow-y-auto\">\n {columns.map((col) => (\n <div\n key={col.id}\n className=\"rounded-[8px] px-2 py-1 hover:bg-neutral-100 dark:hover:bg-neutral-700\"\n >\n <Checkbox\n checked={col.visible !== false}\n onChange={() => onToggle(col.id)}\n label={col.label}\n />\n </div>\n ))}\n </div>\n\n {(onShowAll || onHideAll) && (\n <div className=\"flex gap-2 border-t border-neutral-200 pt-2 dark:border-neutral-700\">\n {onShowAll && (\n <Button\n onClick={onShowAll}\n size=\"small\"\n className=\"flex-1 border-none bg-transparent px-1 py-1 text-xs font-semibold text-accent shadow-none hover:bg-transparent hover:text-accent-hover hover:opacity-100\"\n >\n SHOW ALL\n </Button>\n )}\n {onHideAll && (\n <Button\n onClick={onHideAll}\n size=\"small\"\n className=\"flex-1 border-none bg-transparent px-1 py-1 text-xs font-semibold text-neutral-500 shadow-none hover:bg-transparent hover:text-neutral-600 hover:opacity-100 dark:text-neutral-300 dark:hover:text-white\"\n >\n HIDE ALL\n </Button>\n )}\n </div>\n )}\n </div>\n);\n\ninterface FilterProfileProps {\n isOpen: boolean;\n onClose: () => void;\n onSaveProfile: (name: string) => void;\n}\n\nexport const FilterProfile: React.FC<FilterProfileProps> = ({\n isOpen,\n onClose,\n onSaveProfile,\n}) => {\n const [profileName, setProfileName] = React.useState(\"\");\n\n const handleSave = () => {\n if (profileName.trim()) {\n onSaveProfile(profileName);\n setProfileName(\"\");\n onClose();\n }\n };\n\n if (!isOpen) return null;\n\n return (\n <div\n className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\"\n onClick={onClose}\n >\n <div\n className=\"bg-white dark:bg-neutral-800 rounded-xl p-6 max-w-md w-full mx-4\"\n onClick={(e) => e.stopPropagation()}\n >\n <h2 className=\"text-2xl font-bold text-neutral-900 dark:text-white mb-4\">\n Add new profile\n </h2>\n\n <label className=\"mb-2 block text-sm font-medium text-accent\">\n Enter filter profile name:\n </label>\n <Input\n type=\"text\"\n value={profileName}\n onChange={(e) => setProfileName(e.target.value)}\n placeholder=\"Enter value\"\n className=\"\"\n onKeyDown={(e) => e.key === \"Enter\" && handleSave()}\n />\n\n <div className=\"flex justify-end gap-3 mt-6\">\n <Button onClick={onClose} className=\"min-w-28\" size=\"medium\">\n Cancel\n </Button>\n <Button\n onClick={handleSave}\n disabled={!profileName.trim()}\n className=\"min-w-28\"\n size=\"medium\"\n primary\n >\n Save\n </Button>\n </div>\n </div>\n </div>\n );\n};\n\ntype AsyncFilterOptionsState = Record<\n string,\n { options: string[]; isLoading: boolean }\n>;\n\ntype NumberRangeFilterValue = { min?: number; max?: number };\n\nconst ICON_BUTTON_CLASS_NAME =\n \"inline-flex items-center justify-center rounded-lg text-neutral-400 transition-colors hover:bg-neutral-100 hover:text-neutral-600 dark:hover:bg-neutral-700\";\nconst DISABLED_ICON_BUTTON_CLASS_NAME = `${ICON_BUTTON_CLASS_NAME} disabled:opacity-40 disabled:cursor-not-allowed`;\nconst TABLE_CONTROL_ICON_CLASS_NAME = \"h-[18px] w-[18px] shrink-0\";\nconst TABLE_COMPLEX_ICON_CLASS_NAME = \"h-5 w-5 shrink-0\";\n\nconst isFilterValueEmpty = (value?: FilterValue | null): boolean => {\n if (value === undefined || value === null) {\n return true;\n }\n\n if (typeof value === \"string\") {\n return value === \"\";\n }\n\n if (Array.isArray(value)) {\n return value.length === 0;\n }\n\n if (value instanceof Date || typeof value === \"boolean\") {\n return false;\n }\n\n if (\"start\" in value || \"end\" in value) {\n const rangeValue = value as DateRangeValue;\n return !rangeValue.start && !rangeValue.end;\n }\n\n return value.min === undefined && value.max === undefined;\n};\n\nconst isFilterActive = (value?: FilterValue): boolean =>\n !isFilterValueEmpty(value);\n\nconst toSelectOptions = (options?: string[]) =>\n (options || []).map((option) => ({\n value: option,\n label: option,\n }));\n\nconst getStringFilterValue = (value?: FilterValue): string =>\n typeof value === \"string\" ? value : \"\";\n\nconst getMultiStringFilterValue = (value?: FilterValue): string[] => {\n if (Array.isArray(value)) {\n return value;\n }\n\n return typeof value === \"string\" && value ? [value] : [];\n};\n\nconst getNumberRangeFilterValue = (\n value?: FilterValue,\n): NumberRangeFilterValue => {\n if (\n !value ||\n typeof value !== \"object\" ||\n \"start\" in value ||\n \"end\" in value\n ) {\n return {};\n }\n\n return value as NumberRangeFilterValue;\n};\n\nconst getDateFilterValue = (value?: FilterValue): DatePickerValue =>\n value instanceof Date || value === null ? value : null;\n\nconst getDateRangeFilterValue = (value?: FilterValue): DateRangeValue => {\n if (\n value &&\n typeof value === \"object\" &&\n \"start\" in value &&\n \"end\" in value\n ) {\n return value as DateRangeValue;\n }\n\n return { start: null, end: null };\n};\n\nfunction buildGeneratedFilterOptions<T>(\n columns: DataTableProps<T>[\"columns\"],\n data: T[],\n): FilterOption[] {\n return columns\n .filter((column) => column.filterable !== false)\n .map((column) => {\n const uniqueValues = new Set<string>();\n\n data.forEach((row) => {\n const value = (row as Record<string, unknown>)[column.id];\n if (value !== undefined && value !== null && value !== \"\") {\n uniqueValues.add(String(value));\n }\n });\n\n return {\n id: column.id,\n label: column.label,\n options: Array.from(uniqueValues).sort(),\n multiple: column.multiFilter,\n };\n });\n}\n\nfunction resolveFilterOptions<T>(\n columns: DataTableProps<T>[\"columns\"],\n data: T[],\n externalFilterOptions: FilterOption[] | undefined,\n asyncFilterOptions: AsyncFilterOptionsState,\n): FilterOption[] {\n if (!externalFilterOptions?.length) {\n return buildGeneratedFilterOptions(columns, data);\n }\n\n return externalFilterOptions.map((filter) => {\n const asyncState = asyncFilterOptions[filter.id];\n if (!asyncState) {\n return filter;\n }\n\n return {\n ...filter,\n options: asyncState.options,\n isLoading: asyncState.isLoading,\n };\n });\n}\n\nfunction matchesSearchQuery<T>(row: T, searchQuery: string): boolean {\n if (!searchQuery.trim()) {\n return true;\n }\n\n const query = searchQuery.toLowerCase();\n return Object.values(row as Record<string, unknown>).some((value) => {\n if (value === undefined || value === null) {\n return false;\n }\n\n return String(value).toLowerCase().includes(query);\n });\n}\n\nfunction matchesFilterValue(\n rowValue: unknown,\n filterValue: FilterValue,\n filterOption?: FilterOption,\n): boolean {\n if (isFilterValueEmpty(filterValue)) {\n return true;\n }\n\n switch (filterOption?.type) {\n case \"text\":\n return String(rowValue)\n .toLowerCase()\n .includes(String(filterValue).toLowerCase());\n case \"number-range\": {\n const rangeValue = getNumberRangeFilterValue(filterValue);\n const numericValue = Number(rowValue);\n if (rangeValue.min !== undefined && numericValue < rangeValue.min) {\n return false;\n }\n if (rangeValue.max !== undefined && numericValue > rangeValue.max) {\n return false;\n }\n return true;\n }\n case \"date-range\": {\n const rangeValue = getDateRangeFilterValue(filterValue);\n if (!rangeValue.start) {\n return true;\n }\n const timeValue = new Date(rowValue as string | number | Date).getTime();\n if (timeValue < rangeValue.start.getTime()) {\n return false;\n }\n return !rangeValue.end || timeValue <= rangeValue.end.getTime();\n }\n case \"date\": {\n const selectedDate = filterValue as Date;\n const rowDate = new Date(rowValue as string | number | Date);\n return selectedDate.toDateString() === rowDate.toDateString();\n }\n case \"switch\":\n case \"checkbox\":\n return Boolean(rowValue) === Boolean(filterValue);\n default: {\n const rowValueString = String(rowValue).toLowerCase();\n if (Array.isArray(filterValue)) {\n return filterValue.some(\n (value) => String(value).toLowerCase() === rowValueString,\n );\n }\n\n return typeof filterValue !== \"string\"\n ? true\n : rowValueString === filterValue.toLowerCase();\n }\n }\n}\n\nfunction filterClientData<T>(\n data: T[],\n activeFilters: FilterValues,\n searchQuery: string,\n serverSideFiltering: boolean,\n filterOptions: FilterOption[],\n): T[] {\n if (serverSideFiltering) {\n return data;\n }\n\n const filterOptionsMap = new Map(\n filterOptions.map((filterOption) => [filterOption.id, filterOption]),\n );\n\n return data.filter((row) => {\n if (!matchesSearchQuery(row, searchQuery)) {\n return false;\n }\n\n return Object.entries(activeFilters).every(([filterId, filterValue]) => {\n const rowValue = (row as Record<string, unknown>)[filterId];\n return matchesFilterValue(\n rowValue,\n filterValue,\n filterOptionsMap.get(filterId),\n );\n });\n });\n}\n\nfunction useAsyncFilterOptions(\n externalFilterOptions: FilterOption[] | undefined,\n filterSelectorOpen: boolean,\n): AsyncFilterOptionsState {\n const [asyncFilterOptions, setAsyncFilterOptions] =\n React.useState<AsyncFilterOptionsState>({});\n const asyncFilterOptionsRef = React.useRef(asyncFilterOptions);\n\n React.useEffect(() => {\n asyncFilterOptionsRef.current = asyncFilterOptions;\n }, [asyncFilterOptions]);\n\n const fetchAsyncOptions = React.useCallback(async (filter: FilterOption) => {\n if (\n !filter.fetchOptions ||\n asyncFilterOptionsRef.current[filter.id]?.options.length\n ) {\n return;\n }\n\n setAsyncFilterOptions((prev) => ({\n ...prev,\n [filter.id]: { options: [], isLoading: true },\n }));\n\n try {\n const options = await filter.fetchOptions();\n setAsyncFilterOptions((prev) => ({\n ...prev,\n [filter.id]: { options, isLoading: false },\n }));\n } catch {\n setAsyncFilterOptions((prev) => ({\n ...prev,\n [filter.id]: { options: [], isLoading: false },\n }));\n }\n }, []);\n\n React.useEffect(() => {\n if (!filterSelectorOpen || !externalFilterOptions) {\n return;\n }\n\n externalFilterOptions.forEach((filter) => {\n if (filter.fetchOptions) {\n void fetchAsyncOptions(filter);\n }\n });\n }, [externalFilterOptions, fetchAsyncOptions, filterSelectorOpen]);\n\n return asyncFilterOptions;\n}\n\nfunction LoadingFilterField({ label }: { label: string }) {\n return (\n <div className=\"h-10 flex items-center justify-center bg-neutral-100 dark:bg-neutral-800 rounded-md px-3\">\n <LoaderIcon\n className=\"w-4 h-4 animate-spin text-neutral-400\"\n aria-hidden=\"true\"\n />\n <span className=\"ml-2 text-sm text-neutral-500\">{label}</span>\n </div>\n );\n}\n\ninterface NumberRangeFilterProps {\n value: NumberRangeFilterValue;\n onChange: (value: NumberRangeFilterValue) => void;\n}\n\nfunction NumberRangeFilter({ value, onChange }: NumberRangeFilterProps) {\n return (\n <div className=\"flex items-center gap-1\">\n <Input\n type=\"number\"\n placeholder=\"Min\"\n value={value.min ?? \"\"}\n onChange={(event) => {\n const min =\n event.target.value === \"\" ? undefined : Number(event.target.value);\n onChange({ ...value, min });\n }}\n className=\"h-9 px-2 text-xs\"\n />\n <span className=\"text-neutral-400\">-</span>\n <Input\n type=\"number\"\n placeholder=\"Max\"\n value={value.max ?? \"\"}\n onChange={(event) => {\n const max =\n event.target.value === \"\" ? undefined : Number(event.target.value);\n onChange({ ...value, max });\n }}\n className=\"h-9 px-2 text-xs\"\n />\n </div>\n );\n}\n\ninterface FilterFieldControlProps {\n filter: FilterOption;\n value?: FilterValue;\n isActive: boolean;\n onChange: (value: FilterValue) => void;\n}\n\nfunction FilterFieldControl({\n filter,\n value,\n isActive,\n onChange,\n}: FilterFieldControlProps) {\n if (filter.isLoading) {\n return <LoadingFilterField label={filter.label} />;\n }\n\n const activeClassName = isActive ? \"border-accent\" : \"\";\n\n switch (filter.type) {\n case \"text\":\n return (\n <Input\n value={getStringFilterValue(value)}\n onChange={(event) => onChange(event.target.value)}\n placeholder={filter.placeholder || filter.label}\n className={activeClassName}\n />\n );\n case \"select\":\n return (\n <Select\n value={getStringFilterValue(value)}\n onChange={(event) => onChange(event.target.value)}\n placeholder={filter.placeholder || filter.label}\n options={toSelectOptions(filter.options)}\n className={activeClassName}\n />\n );\n case \"switch\":\n case \"checkbox\":\n return (\n <Switch\n checked={Boolean(value)}\n onChange={(event) => onChange(event.target.checked)}\n label={filter.label}\n />\n );\n case \"date\":\n return (\n <DatePicker\n mode=\"single\"\n value={getDateFilterValue(value)}\n onChange={(nextValue) => onChange(nextValue)}\n placeholder={filter.placeholder || filter.label}\n />\n );\n case \"date-range\":\n return (\n <DatePicker\n mode=\"range\"\n value={getDateRangeFilterValue(value)}\n onChange={(nextValue) => onChange(nextValue)}\n placeholder={filter.placeholder || filter.label}\n />\n );\n case \"number-range\":\n return (\n <NumberRangeFilter\n value={getNumberRangeFilterValue(value)}\n onChange={onChange}\n />\n );\n default:\n return filter.multiple ? (\n <MultiSelectCombobox\n value={getMultiStringFilterValue(value)}\n onChange={(values) => onChange(values)}\n placeholder={filter.placeholder || filter.label}\n options={toSelectOptions(filter.options)}\n className={isActive ? \"border-accent border-2\" : \"\"}\n />\n ) : (\n <Combobox\n value={getStringFilterValue(value)}\n onChange={(nextValue) => onChange(nextValue)}\n placeholder={filter.placeholder || filter.label}\n options={toSelectOptions(filter.options)}\n className={isActive ? \"border-accent border-2\" : \"\"}\n />\n );\n }\n}\n\ninterface ToolbarIconButtonProps {\n title: string;\n onClick?: () => void;\n disabled?: boolean;\n children: React.ReactNode;\n}\n\nfunction ToolbarIconButton({\n title,\n onClick,\n disabled,\n children,\n}: ToolbarIconButtonProps) {\n return (\n <Button\n onClick={onClick}\n disabled={disabled}\n title={title}\n aria-label={title}\n className={\n disabled\n ? `${DISABLED_ICON_BUTTON_CLASS_NAME} h-10 w-10 shrink-0 border-transparent bg-transparent px-0 py-0 text-base shadow-none hover:bg-transparent hover:opacity-100`\n : `${ICON_BUTTON_CLASS_NAME} h-10 w-10 shrink-0 border-transparent bg-transparent px-0 py-0 text-base shadow-none hover:opacity-100`\n }\n >\n {children}\n </Button>\n );\n}\n\ninterface SearchFieldProps {\n value: string;\n onChange: (value: string) => void;\n placeholder: string;\n}\n\nfunction SearchField({ value, onChange, placeholder }: SearchFieldProps) {\n return (\n <div className=\"relative w-[300px]\">\n <SearchIcon\n className={`pointer-events-none absolute left-4 top-1/2 z-10 -translate-y-1/2 text-neutral-400 ${TABLE_CONTROL_ICON_CLASS_NAME}`}\n aria-hidden=\"true\"\n />\n <Input\n type=\"text\"\n value={value}\n onChange={(event) => onChange(event.target.value)}\n placeholder={placeholder}\n style={{ paddingLeft: \"2.75rem\" }}\n />\n </div>\n );\n}\n\ninterface RowActionsCellProps<T> {\n rowIndex: number;\n row: T;\n isOpen: boolean;\n onToggle: (rowIndex: number) => void;\n onClose: () => void;\n onRowAction?: (action: string, row: T) => void;\n}\n\nfunction RowActionsCell<T>({\n rowIndex,\n row,\n isOpen,\n onToggle,\n onClose,\n onRowAction,\n}: RowActionsCellProps<T>) {\n return (\n <td className=\"px-2 py-3 text-right relative\">\n <Button\n onClick={() => onToggle(rowIndex)}\n aria-label=\"Open row actions\"\n className=\"h-8 w-8 border-none bg-transparent px-0 py-0 text-neutral-500 shadow-none hover:bg-neutral-100 hover:text-neutral-700 hover:opacity-100 dark:hover:bg-neutral-600 dark:hover:text-neutral-200\"\n >\n <EllipsisVerticalIcon\n className={TABLE_CONTROL_ICON_CLASS_NAME}\n aria-hidden=\"true\"\n />\n </Button>\n {isOpen ? (\n <>\n <div className=\"fixed inset-0 z-40\" onClick={onClose} />\n <div className=\"absolute right-0 top-full mt-1 bg-white dark:bg-neutral-800 rounded-lg shadow-lg border border-neutral-200 dark:border-neutral-700 z-50 min-w-32 py-1\">\n <Button\n onClick={() => {\n onRowAction?.(\"edit\", row);\n onClose();\n }}\n className=\"w-full justify-start rounded-none border-none bg-transparent px-4 py-2 text-sm font-normal text-neutral-700 shadow-none hover:bg-neutral-50 hover:text-neutral-900 hover:opacity-100 dark:text-neutral-200 dark:hover:bg-neutral-700 dark:hover:text-white\"\n >\n Edit\n </Button>\n <Button\n onClick={() => {\n onRowAction?.(\"delete\", row);\n onClose();\n }}\n className=\"w-full justify-start rounded-none border-none bg-transparent px-4 py-2 text-sm font-normal text-error shadow-none hover:bg-neutral-50 hover:text-error hover:opacity-100 dark:hover:bg-neutral-700\"\n >\n Delete\n </Button>\n </div>\n </>\n ) : null}\n </td>\n );\n}\n\ninterface DataTablePaginationProps<T> {\n table: Table<T>;\n totalCount?: number;\n filteredCount: number;\n}\n\nfunction DataTablePagination<T>({\n table,\n totalCount,\n filteredCount,\n}: DataTablePaginationProps<T>) {\n const { pageIndex, pageSize } = table.getState().pagination;\n const itemCount = totalCount ?? filteredCount;\n const pageStart = itemCount === 0 ? 0 : pageIndex * pageSize + 1;\n const pageEnd = Math.min((pageIndex + 1) * pageSize, itemCount);\n\n return (\n <div className=\"flex items-center justify-between px-4 py-3 border-t border-neutral-200 dark:border-neutral-700 bg-neutral-50 dark:bg-neutral-800/50\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm text-neutral-600 dark:text-neutral-400\">\n Showing {pageStart} to {pageEnd} of {itemCount} items\n </span>\n </div>\n\n <div className=\"flex flex-wrap items-center justify-end gap-2\">\n <span className=\"text-sm text-neutral-600 dark:text-neutral-400\">\n Rows\n </span>\n <Select\n value={String(pageSize)}\n onChange={(event) => table.setPageSize(Number(event.target.value))}\n aria-label=\"Rows per page\"\n containerClassName=\"w-24 min-w-24 shrink-0\"\n triggerClassName=\"px-3 font-medium text-neutral-900 dark:text-white\"\n options={[10, 20, 30, 50, 100].map((size) => ({\n value: String(size),\n label: String(size),\n }))}\n />\n\n <ToolbarIconButton\n title=\"First page\"\n onClick={() => table.setPageIndex(0)}\n disabled={!table.getCanPreviousPage()}\n >\n <ChevronsLeftIcon\n className={TABLE_CONTROL_ICON_CLASS_NAME}\n aria-hidden=\"true\"\n />\n </ToolbarIconButton>\n\n <ToolbarIconButton\n title=\"Previous page\"\n onClick={() => table.previousPage()}\n disabled={!table.getCanPreviousPage()}\n >\n <ChevronLeftIcon\n className={TABLE_CONTROL_ICON_CLASS_NAME}\n aria-hidden=\"true\"\n />\n </ToolbarIconButton>\n\n <span className=\"inline-flex h-10 shrink-0 items-center rounded-lg px-3 text-sm font-medium text-neutral-700 dark:text-neutral-300\">\n Page {pageIndex + 1} of {table.getPageCount()}\n </span>\n\n <ToolbarIconButton\n title=\"Next page\"\n onClick={() => table.nextPage()}\n disabled={!table.getCanNextPage()}\n >\n <ChevronRightIcon\n className={TABLE_CONTROL_ICON_CLASS_NAME}\n aria-hidden=\"true\"\n />\n </ToolbarIconButton>\n\n <ToolbarIconButton\n title=\"Last page\"\n onClick={() => table.setPageIndex(table.getPageCount() - 1)}\n disabled={!table.getCanNextPage()}\n >\n <ChevronsRightIcon\n className={TABLE_CONTROL_ICON_CLASS_NAME}\n aria-hidden=\"true\"\n />\n </ToolbarIconButton>\n </div>\n </div>\n );\n}\n\ninterface FilterSelectorMenuProps {\n filterOptions: FilterOption[];\n visibleFilters: string[];\n onToggleFilter: (filterId: string, isVisible: boolean) => void;\n onShowAll: () => void;\n onHideAll: () => void;\n}\n\nfunction FilterSelectorMenu({\n filterOptions,\n visibleFilters,\n onToggleFilter,\n onShowAll,\n onHideAll,\n}: FilterSelectorMenuProps) {\n return (\n <div className=\"p-2 min-w-48 space-y-1\">\n <div className=\"px-2 pb-2 text-xs font-semibold text-neutral-500 dark:text-neutral-300\">\n Show filters\n </div>\n {filterOptions.map((filter) => (\n <div key={filter.id} className=\"min-w-36\">\n <Checkbox\n checked={visibleFilters.includes(filter.id)}\n onChange={(event) =>\n onToggleFilter(filter.id, event.target.checked)\n }\n label={filter.label}\n />\n </div>\n ))}\n <div className=\"flex gap-2 border-t border-neutral-200 pt-2 dark:border-neutral-700\">\n <Button\n onClick={onShowAll}\n size=\"small\"\n className=\"flex-1 border-none bg-transparent px-1 py-1 text-xs font-semibold text-accent shadow-none hover:bg-transparent hover:text-accent-hover hover:opacity-100\"\n >\n SHOW ALL\n </Button>\n <Button\n onClick={onHideAll}\n size=\"small\"\n className=\"flex-1 border-none bg-transparent px-1 py-1 text-xs font-semibold text-neutral-500 shadow-none hover:bg-transparent hover:text-neutral-600 hover:opacity-100 dark:text-neutral-300 dark:hover:text-white\"\n >\n HIDE ALL\n </Button>\n </div>\n </div>\n );\n}\n\ninterface DataTableToolbarProps<T> {\n searchQuery: string;\n onSearchChange: (value: string) => void;\n searchPlaceholder: string;\n bulkDeleteEnabled: boolean;\n bulkSelectionActive: boolean;\n selectedCount: number;\n bulkActionsContent?: React.ReactNode;\n bulkActionCard?: React.ReactNode;\n onToggleBulkSelection: () => void;\n onBulkDeleteSelected: () => void;\n onExport?: () => void;\n columnMenuOpen: boolean;\n onToggleColumnMenu: () => void;\n onCloseColumnMenu: () => void;\n columns: DataTableProps<T>[\"columns\"];\n onColumnToggle?: (columnId: string) => void;\n onShowAllColumns: () => void;\n onHideAllColumns: () => void;\n}\n\nfunction DataTableToolbar<T>({\n searchQuery,\n onSearchChange,\n searchPlaceholder,\n bulkDeleteEnabled,\n bulkSelectionActive,\n selectedCount,\n bulkActionsContent,\n bulkActionCard,\n onToggleBulkSelection,\n onBulkDeleteSelected,\n onExport,\n columnMenuOpen,\n onToggleColumnMenu,\n onCloseColumnMenu,\n columns,\n onColumnToggle,\n onShowAllColumns,\n onHideAllColumns,\n}: DataTableToolbarProps<T>) {\n const hasSelectedRows = selectedCount > 0;\n\n return (\n <div className=\"border-b border-neutral-200 px-4 py-3 dark:border-neutral-700\">\n <div className=\"flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between\">\n <div className=\"flex min-w-0 flex-1 flex-wrap items-center gap-2\">\n {bulkDeleteEnabled ? (\n <FilterButton\n icon={\n <SelectionIcon\n className={TABLE_COMPLEX_ICON_CLASS_NAME}\n aria-hidden=\"true\"\n />\n }\n label={\n bulkSelectionActive\n ? \"Disable bulk selection\"\n : \"Enable bulk selection\"\n }\n onClick={onToggleBulkSelection}\n hasActive={bulkSelectionActive}\n />\n ) : null}\n\n <SearchField\n value={searchQuery}\n onChange={onSearchChange}\n placeholder={searchPlaceholder}\n />\n </div>\n\n <div className=\"flex items-center gap-1 self-end lg:self-auto\">\n <ToolbarIconButton onClick={onExport} title=\"Refresh\">\n <RefreshIcon\n className={TABLE_CONTROL_ICON_CLASS_NAME}\n aria-hidden=\"true\"\n />\n </ToolbarIconButton>\n\n <div className=\"relative\">\n <ToolbarIconButton\n onClick={onToggleColumnMenu}\n title=\"Column settings\"\n >\n <SettingsIcon\n className={TABLE_COMPLEX_ICON_CLASS_NAME}\n aria-hidden=\"true\"\n />\n </ToolbarIconButton>\n\n <FilterDropdown isOpen={columnMenuOpen} onClose={onCloseColumnMenu}>\n <ColumnToggle\n columns={columns}\n onToggle={(columnId) => {\n onColumnToggle?.(columnId);\n }}\n onShowAll={onShowAllColumns}\n onHideAll={onHideAllColumns}\n />\n </FilterDropdown>\n </div>\n </div>\n </div>\n\n {bulkSelectionActive && hasSelectedRows\n ? (bulkActionCard ?? (\n <div className=\"mt-2 flex flex-col gap-2 rounded-[4px] border border-neutral-200 bg-neutral-50 px-3 py-2 shadow-sm dark:border-neutral-700 dark:bg-neutral-800/50 dark:shadow-black/25 lg:flex-row lg:items-center lg:justify-between\">\n <div className=\"flex min-w-0 flex-wrap items-center gap-2\">\n <Chip\n variant=\"soft\"\n color=\"primary\"\n size=\"sm\"\n className=\"uppercase tracking-wide\"\n >\n Bulk actions\n </Chip>\n <p className=\"text-sm font-medium text-neutral-900 dark:text-white\">\n {selectedCount} {selectedCount === 1 ? \"row\" : \"rows\"}{\" \"}\n selected\n </p>\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2\">\n {bulkActionsContent}\n {bulkDeleteEnabled ? (\n <Button\n onClick={onBulkDeleteSelected}\n primary\n size=\"small\"\n className=\"border-accent/20 px-3 py-2 text-sm text-on-accent shadow-lg shadow-accent/20 hover:bg-accent-hover hover:opacity-100\"\n >\n <TrashIcon className=\"h-4 w-4\" aria-hidden=\"true\" />\n Delete selected\n </Button>\n ) : null}\n </div>\n </div>\n ))\n : null}\n </div>\n );\n}\n\ninterface TableStateRowProps {\n colSpan: number;\n children: React.ReactNode;\n}\n\nfunction TableStateRow({ colSpan, children }: TableStateRowProps) {\n return (\n <tr>\n <td colSpan={colSpan} className=\"px-4 py-12 text-center text-neutral-500\">\n {children}\n </td>\n </tr>\n );\n}\n\nfunction LoadingTableState({ colSpan }: { colSpan: number }) {\n return (\n <TableStateRow colSpan={colSpan}>\n <div className=\"flex flex-col items-center gap-3\">\n <LoaderIcon\n className=\"w-8 h-8 animate-spin text-accent\"\n aria-hidden=\"true\"\n />\n <span>Loading data...</span>\n </div>\n </TableStateRow>\n );\n}\n\nfunction EmptyTableState({ colSpan }: { colSpan: number }) {\n return (\n <TableStateRow colSpan={colSpan}>\n <div className=\"flex flex-col items-center gap-2\">\n <span className=\"text-4xl\">🔍</span>\n <p className=\"font-medium\">No results found</p>\n <p className=\"text-sm\">Try adjusting the filter</p>\n </div>\n </TableStateRow>\n );\n}\n\ninterface DataTableRowsProps<T> {\n table: Table<T>;\n isLoading: boolean;\n bulkSelectionActive: boolean;\n selectedRowIds: Record<string, boolean>;\n onToggleRowSelection: (rowId: string, checked: boolean) => void;\n rowMenuOpen: number | null;\n onToggleRowMenu: (rowIndex: number) => void;\n onCloseRowMenu: () => void;\n onRowAction?: (action: string, row: T) => void;\n}\n\nfunction DataTableRows<T>({\n table,\n isLoading,\n bulkSelectionActive,\n selectedRowIds,\n onToggleRowSelection,\n rowMenuOpen,\n onToggleRowMenu,\n onCloseRowMenu,\n onRowAction,\n}: DataTableRowsProps<T>) {\n const colSpan =\n table.getVisibleLeafColumns().length + (bulkSelectionActive ? 2 : 1);\n\n if (isLoading) {\n return <LoadingTableState colSpan={colSpan} />;\n }\n\n if (table.getRowModel().rows.length === 0) {\n return <EmptyTableState colSpan={colSpan} />;\n }\n\n return (\n <>\n {table.getRowModel().rows.map((row) => (\n <tr\n key={row.id}\n className=\"border-b border-neutral-100 dark:border-neutral-700 hover:bg-neutral-50 dark:hover:bg-neutral-700/50 transition-colors\"\n >\n {bulkSelectionActive ? (\n <td className=\"w-12 px-4 py-3 align-middle\">\n <Checkbox\n aria-label={`Select row ${row.id}`}\n checked={Boolean(selectedRowIds[row.id])}\n onChange={(event) =>\n onToggleRowSelection(row.id, event.target.checked)\n }\n />\n </td>\n ) : null}\n {row.getVisibleCells().map((cell) => (\n <td\n key={cell.id}\n className=\"px-4 py-3 text-sm text-neutral-700 dark:text-neutral-300\"\n >\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </td>\n ))}\n <RowActionsCell\n rowIndex={row.index}\n row={row.original}\n isOpen={rowMenuOpen === row.index}\n onToggle={onToggleRowMenu}\n onClose={onCloseRowMenu}\n onRowAction={onRowAction}\n />\n </tr>\n ))}\n </>\n );\n}\n\nconst usesManualPagination = (\n totalCount?: number,\n onPaginationChange?: (pageIndex: number, pageSize: number) => void,\n) => totalCount !== undefined || typeof onPaginationChange === \"function\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport default function DataTable<T = Record<string, any>>({\n columns,\n data,\n isLoading = false,\n onColumnToggle,\n pageSize = 10,\n maxHeight = \"500px\",\n onSearch,\n onExport,\n onRowAction,\n onBulkDelete,\n renderBulkActions,\n renderBulkActionCard,\n onFilterChange,\n onFiltersApply,\n serverSideFiltering = false,\n filterOptions: externalFilterOptions,\n searchPlaceholder = \"Search ...\",\n totalCount,\n onPaginationChange,\n}: DataTableProps<T>) {\n const [pagination, setPagination] = React.useState<PaginationState>({\n pageIndex: 0,\n pageSize: pageSize,\n });\n const [columnMenuOpen, setColumnMenuOpen] = React.useState(false);\n const [profileMenuOpen, setProfileMenuOpen] = React.useState(false);\n const [profileOpen, setProfileOpen] = React.useState(false);\n const [filterSelectorOpen, setFilterSelectorOpen] = React.useState(false);\n const [visibleFilters, setVisibleFilters] = React.useState<string[]>([]);\n const [activeFilters, setActiveFilters] = React.useState<FilterValues>({});\n const [bulkSelectionActive, setBulkSelectionActive] = React.useState(false);\n const [selectedRowIds, setSelectedRowIds] = React.useState<\n Record<string, boolean>\n >({});\n const [rowMenuOpen, setRowMenuOpen] = React.useState<number | null>(null);\n const [searchQuery, setSearchQuery] = React.useState(\"\");\n const [columnVisibility, setColumnVisibility] = React.useState<\n Record<string, boolean>\n >(() =>\n Object.fromEntries(\n columns.map((column) => [column.id, column.visible !== false]),\n ),\n );\n\n const columnsVisibilitySignature = React.useMemo(\n () =>\n columns\n .map((column) => `${column.id}:${column.visible !== false}`)\n .join(\"|\"),\n [columns],\n );\n\n React.useEffect(() => {\n setColumnVisibility(\n Object.fromEntries(\n columns.map((column) => [column.id, column.visible !== false]),\n ),\n );\n }, [columns, columnsVisibilitySignature]);\n\n const asyncFilterOptions = useAsyncFilterOptions(\n externalFilterOptions,\n filterSelectorOpen,\n );\n\n // Auto-generate filter options from columns that are filterable\n const filterOptions: FilterOption[] = React.useMemo(() => {\n return resolveFilterOptions(\n columns,\n data,\n externalFilterOptions,\n asyncFilterOptions,\n );\n }, [columns, data, externalFilterOptions, asyncFilterOptions]);\n\n const resolvedColumns = React.useMemo(\n () =>\n columns.map((column) => ({\n ...column,\n visible: columnVisibility[column.id] ?? column.visible !== false,\n })),\n [columnVisibility, columns],\n );\n\n const visibleColumns = React.useMemo(\n () => resolvedColumns.filter((column) => column.visible !== false),\n [resolvedColumns],\n );\n const manualPagination = usesManualPagination(totalCount, onPaginationChange);\n const pageCount =\n totalCount === undefined\n ? undefined\n : Math.ceil(totalCount / pagination.pageSize);\n\n // Filter data based on search query and active filters (client-side only)\n const filteredData = React.useMemo(() => {\n return filterClientData(\n data,\n activeFilters,\n searchQuery,\n serverSideFiltering,\n filterOptions,\n );\n }, [data, activeFilters, searchQuery, serverSideFiltering, filterOptions]);\n\n // TanStack Table columns definition\n const tableColumns = React.useMemo<ColumnDef<T>[]>(\n () =>\n visibleColumns.map((col) => ({\n id: col.id,\n accessorKey: col.id,\n header: col.label,\n cell: (info: CellContext<T, unknown>) => {\n const value = info.getValue();\n\n if (col.renderCell) {\n return col.renderCell({\n value,\n row: info.row.original,\n rowIndex: info.row.index,\n columnId: col.id,\n });\n }\n\n return renderDefaultCellValue(value);\n },\n })),\n [visibleColumns],\n );\n\n const updatePagination = React.useCallback(\n (\n updater:\n | PaginationState\n | ((previous: PaginationState) => PaginationState),\n ) => {\n setPagination((previous) => {\n const nextPagination =\n typeof updater === \"function\" ? updater(previous) : updater;\n\n if (\n previous.pageIndex !== nextPagination.pageIndex ||\n previous.pageSize !== nextPagination.pageSize\n ) {\n onPaginationChange?.(\n nextPagination.pageIndex,\n nextPagination.pageSize,\n );\n }\n\n return nextPagination;\n });\n },\n [onPaginationChange],\n );\n\n const table = useReactTable({\n data: filteredData,\n columns: tableColumns,\n getCoreRowModel: getCoreRowModel(),\n getPaginationRowModel: getPaginationRowModel(),\n getFilteredRowModel: getFilteredRowModel(),\n state: {\n pagination,\n globalFilter: searchQuery,\n },\n onPaginationChange: updatePagination,\n manualPagination,\n pageCount,\n });\n\n const visibleRows = table.getRowModel().rows;\n const bulkDeleteEnabled = typeof onBulkDelete === \"function\";\n const selectedRows = React.useMemo(\n () =>\n visibleRows\n .filter((row) => selectedRowIds[row.id])\n .map((row) => row.original),\n [selectedRowIds, visibleRows],\n );\n const allVisibleRowsSelected =\n visibleRows.length > 0 &&\n visibleRows.every((row) => selectedRowIds[row.id]);\n\n React.useEffect(() => {\n updatePagination((previous) =>\n previous.pageIndex === 0 ? previous : { ...previous, pageIndex: 0 },\n );\n }, [activeFilters, searchQuery, updatePagination]);\n\n React.useEffect(() => {\n setSelectedRowIds((previous) => {\n const visibleRowIds = new Set(visibleRows.map((row) => row.id));\n const nextSelection = Object.fromEntries(\n Object.entries(previous).filter(\n ([rowId, isSelected]) => isSelected && visibleRowIds.has(rowId),\n ),\n );\n\n const previousKeys = Object.keys(previous).sort().join(\"|\");\n const nextKeys = Object.keys(nextSelection).sort().join(\"|\");\n\n return previousKeys === nextKeys ? previous : nextSelection;\n });\n }, [visibleRows]);\n\n const applyFilters = React.useCallback(\n (nextFilters: FilterValues) => {\n setActiveFilters(nextFilters);\n onFilterChange?.(nextFilters);\n\n if (serverSideFiltering) {\n onFiltersApply?.(nextFilters);\n }\n },\n [onFilterChange, onFiltersApply, serverSideFiltering],\n );\n\n const handleSearchChange = React.useCallback(\n (value: string) => {\n setSearchQuery(value);\n onSearch?.(value);\n },\n [onSearch],\n );\n\n const handleFilterChange = React.useCallback(\n (filterId: string, value: FilterValue) => {\n applyFilters({\n ...activeFilters,\n [filterId]: value,\n });\n },\n [activeFilters, applyFilters],\n );\n\n const handleResetFilters = React.useCallback(() => {\n applyFilters({});\n }, [applyFilters]);\n\n const handleToggleFilterVisibility = React.useCallback(\n (filterId: string, isVisible: boolean) => {\n setVisibleFilters((previous) => {\n if (isVisible) {\n return previous.includes(filterId)\n ? previous\n : [...previous, filterId];\n }\n\n return previous.filter((id) => id !== filterId);\n });\n\n if (!isVisible && filterId in activeFilters) {\n const nextFilters = { ...activeFilters };\n delete nextFilters[filterId];\n applyFilters(nextFilters);\n }\n },\n [activeFilters, applyFilters],\n );\n\n const handleShowAllFilters = React.useCallback(() => {\n setVisibleFilters(filterOptions.map((filter) => filter.id));\n }, [filterOptions]);\n\n const handleHideAllFilters = React.useCallback(() => {\n setVisibleFilters([]);\n handleResetFilters();\n }, [handleResetFilters]);\n\n const handleToggleRowMenu = React.useCallback((rowIndex: number) => {\n setRowMenuOpen((previous) => (previous === rowIndex ? null : rowIndex));\n }, []);\n\n const handleToggleFilterSelector = React.useCallback(() => {\n setFilterSelectorOpen((previous) => !previous);\n }, []);\n\n const handleToggleProfileMenu = React.useCallback(() => {\n setProfileMenuOpen((previous) => !previous);\n }, []);\n\n const handleToggleColumnMenu = React.useCallback(() => {\n setColumnMenuOpen((previous) => !previous);\n }, []);\n\n const handleToggleColumnVisibility = React.useCallback(\n (columnId: string) => {\n setColumnVisibility((previous) => ({\n ...previous,\n [columnId]: !(previous[columnId] ?? true),\n }));\n onColumnToggle?.(columnId);\n },\n [onColumnToggle],\n );\n\n const handleShowAllColumns = React.useCallback(() => {\n setColumnVisibility(\n Object.fromEntries(columns.map((column) => [column.id, true])),\n );\n }, [columns]);\n\n const handleHideAllColumns = React.useCallback(() => {\n setColumnVisibility(\n Object.fromEntries(columns.map((column) => [column.id, false])),\n );\n }, [columns]);\n\n const handleToggleBulkSelection = React.useCallback(() => {\n setBulkSelectionActive((previous) => {\n if (previous) {\n setSelectedRowIds({});\n }\n\n return !previous;\n });\n }, []);\n\n const handleToggleRowSelection = React.useCallback(\n (rowId: string, checked: boolean) => {\n setSelectedRowIds((previous) => {\n if (checked) {\n return {\n ...previous,\n [rowId]: true,\n };\n }\n\n const nextSelection = { ...previous };\n delete nextSelection[rowId];\n return nextSelection;\n });\n },\n [],\n );\n\n const handleToggleAllVisibleRows = React.useCallback(\n (checked: boolean) => {\n setSelectedRowIds((previous) => {\n const nextSelection = { ...previous };\n\n visibleRows.forEach((row) => {\n if (checked) {\n nextSelection[row.id] = true;\n } else {\n delete nextSelection[row.id];\n }\n });\n\n return nextSelection;\n });\n },\n [visibleRows],\n );\n\n const handleBulkDeleteSelected = React.useCallback(() => {\n if (!onBulkDelete || selectedRows.length === 0) {\n return;\n }\n\n onBulkDelete(selectedRows);\n setSelectedRowIds({});\n }, [onBulkDelete, selectedRows]);\n\n const handleClearSelectedRows = React.useCallback(() => {\n setSelectedRowIds({});\n }, []);\n\n const handleDisableBulkSelection = React.useCallback(() => {\n setBulkSelectionActive(false);\n setSelectedRowIds({});\n }, []);\n\n const bulkActionContext = React.useMemo<DataTableBulkActionContext<T>>(\n () => ({\n selectedRows,\n selectedCount: selectedRows.length,\n clearSelection: handleClearSelectedRows,\n disableBulkSelection: handleDisableBulkSelection,\n }),\n [handleClearSelectedRows, handleDisableBulkSelection, selectedRows],\n );\n\n const bulkActionsContent = renderBulkActions?.(bulkActionContext);\n const bulkActionCard = renderBulkActionCard?.(bulkActionContext);\n\n const handleOpenProfile = React.useCallback(() => {\n setProfileOpen(true);\n setProfileMenuOpen(false);\n }, []);\n\n const hasActiveFilters = Object.values(activeFilters).some(isFilterActive);\n\n const handleSaveProfile = (profileName: string) => {\n void {\n name: profileName,\n filters: activeFilters,\n timestamp: new Date().toISOString(),\n };\n };\n\n return (\n <div className=\"space-y-0\">\n {/* Row 1: Filters Row - Separated with border */}\n <div className=\"mb-4 flex items-center justify-between gap-4 rounded-[8px] border border-neutral-200 bg-neutral-50 px-4 py-4 dark:border-neutral-700 dark:bg-neutral-800/50\">\n <div className=\"flex items-center gap-3 flex-wrap\">\n {filterOptions\n .filter((filter) => visibleFilters.includes(filter.id))\n .map((filter, index) => {\n const isActive = isFilterActive(activeFilters[filter.id]);\n\n return (\n <div\n key={filter.id}\n className={`min-w-[200px] ${\n index > 0\n ? \"border-l border-neutral-200 pl-3 dark:border-neutral-600\"\n : \"\"\n }`}\n >\n <FilterFieldControl\n filter={filter}\n value={activeFilters[filter.id]}\n isActive={isActive}\n onChange={(value) => handleFilterChange(filter.id, value)}\n />\n </div>\n );\n })}\n </div>\n\n {/* Right side icons */}\n <div className=\"flex items-center gap-1 ml-auto\">\n <div className=\"relative\">\n <ToolbarIconButton\n onClick={handleToggleFilterSelector}\n title=\"Add filter\"\n >\n <FilterIcon\n className={TABLE_COMPLEX_ICON_CLASS_NAME}\n aria-hidden=\"true\"\n />\n </ToolbarIconButton>\n <FilterDropdown\n isOpen={filterSelectorOpen}\n onClose={() => setFilterSelectorOpen(false)}\n >\n <FilterSelectorMenu\n filterOptions={filterOptions}\n visibleFilters={visibleFilters}\n onToggleFilter={handleToggleFilterVisibility}\n onShowAll={handleShowAllFilters}\n onHideAll={handleHideAllFilters}\n />\n </FilterDropdown>\n </div>\n\n <ToolbarIconButton\n onClick={handleResetFilters}\n disabled={!hasActiveFilters}\n title=\"Clear filters\"\n >\n <FilterXIcon\n className={TABLE_COMPLEX_ICON_CLASS_NAME}\n aria-hidden=\"true\"\n />\n </ToolbarIconButton>\n\n <div className=\"relative\">\n <ToolbarIconButton\n onClick={handleToggleProfileMenu}\n title=\"Filter profiles\"\n >\n <FilterProfileIcon\n className={TABLE_COMPLEX_ICON_CLASS_NAME}\n aria-hidden=\"true\"\n />\n </ToolbarIconButton>\n <FilterDropdown\n isOpen={profileMenuOpen}\n onClose={() => setProfileMenuOpen(false)}\n >\n <div className=\"p-2 min-w-48\">\n <Button\n onClick={handleOpenProfile}\n className=\"w-full justify-start border-2 border-dashed border-accent/40 bg-transparent px-4 py-3 text-left text-sm font-medium text-accent shadow-none hover:bg-accent-subtle hover:opacity-100\"\n >\n Save new filter profile\n </Button>\n </div>\n </FilterDropdown>\n </div>\n </div>\n </div>\n\n {/* Table */}\n <div className=\"bg-background-secondary rounded-lg border border-neutral-200 dark:border-neutral-700 overflow-hidden\">\n <DataTableToolbar\n searchQuery={searchQuery}\n onSearchChange={handleSearchChange}\n searchPlaceholder={searchPlaceholder}\n bulkDeleteEnabled={bulkDeleteEnabled}\n bulkSelectionActive={bulkSelectionActive}\n selectedCount={selectedRows.length}\n bulkActionsContent={bulkActionsContent}\n bulkActionCard={bulkActionCard}\n onToggleBulkSelection={handleToggleBulkSelection}\n onBulkDeleteSelected={handleBulkDeleteSelected}\n onExport={onExport}\n columnMenuOpen={columnMenuOpen}\n onToggleColumnMenu={handleToggleColumnMenu}\n onCloseColumnMenu={() => setColumnMenuOpen(false)}\n columns={resolvedColumns}\n onColumnToggle={handleToggleColumnVisibility}\n onShowAllColumns={handleShowAllColumns}\n onHideAllColumns={handleHideAllColumns}\n />\n\n {/* Table Container */}\n <div className=\"overflow-auto\" style={{ maxHeight }}>\n <table className=\"w-full min-w-[600px]\">\n <thead className=\"sticky top-0 z-10 bg-background-secondary\">\n {table.getHeaderGroups().map((headerGroup) => (\n <tr\n key={headerGroup.id}\n className=\"border-b border-neutral-200 dark:border-neutral-700\"\n >\n {bulkSelectionActive ? (\n <th className=\"w-12 px-4 py-3 bg-background-secondary\">\n <Checkbox\n aria-label=\"Select all visible rows\"\n checked={allVisibleRowsSelected}\n onChange={(event) =>\n handleToggleAllVisibleRows(event.target.checked)\n }\n />\n </th>\n ) : null}\n {headerGroup.headers.map((header) => (\n <th\n key={header.id}\n className=\"bg-background-secondary px-4 py-3 text-left text-sm font-semibold text-neutral-900 dark:text-white whitespace-nowrap\"\n >\n {header.isPlaceholder\n ? null\n : flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )}\n </th>\n ))}\n <th className=\"w-12 bg-background-secondary\"></th>\n </tr>\n ))}\n </thead>\n <tbody>\n <DataTableRows\n table={table}\n isLoading={isLoading}\n bulkSelectionActive={bulkSelectionActive}\n selectedRowIds={selectedRowIds}\n onToggleRowSelection={handleToggleRowSelection}\n rowMenuOpen={rowMenuOpen}\n onToggleRowMenu={handleToggleRowMenu}\n onCloseRowMenu={() => setRowMenuOpen(null)}\n onRowAction={onRowAction}\n />\n </tbody>\n </table>\n </div>\n\n <DataTablePagination\n table={table}\n totalCount={totalCount}\n filteredCount={filteredData.length}\n />\n </div>\n\n {/* Profile Modal */}\n <FilterProfile\n isOpen={profileOpen}\n onClose={() => setProfileOpen(false)}\n onSaveProfile={(name) => {\n handleSaveProfile(name);\n setProfileOpen(false);\n }}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { t as Calendar } from "./calendar-
|
|
1
|
+
import { t as Calendar } from "./calendar-DrCgT_pj.mjs";
|
|
2
2
|
import { useEffect, useMemo, useRef, useState } from "react";
|
|
3
3
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
4
|
import { motion, useMotionTemplate, useMotionValue } from "framer-motion";
|
|
5
|
+
import { createPortal } from "react-dom";
|
|
5
6
|
//#region src/components/forms/date-picker/DatePicker.tsx
|
|
6
7
|
var formatDate = (date) => date?.toLocaleDateString(void 0, {
|
|
7
8
|
month: "short",
|
|
@@ -13,6 +14,8 @@ var emptyRange = {
|
|
|
13
14
|
start: null,
|
|
14
15
|
end: null
|
|
15
16
|
};
|
|
17
|
+
var PANEL_GAP = 8;
|
|
18
|
+
var VIEWPORT_MARGIN = 12;
|
|
16
19
|
var DatePicker = ({ mode = "single", value, onChange, label, placeholder = "Pick a date", helperText, disabled = false, className = "", presets }) => {
|
|
17
20
|
const [open, setOpen] = useState(false);
|
|
18
21
|
const [visible, setVisible] = useState(false);
|
|
@@ -39,18 +42,68 @@ var DatePicker = ({ mode = "single", value, onChange, label, placeholder = "Pick
|
|
|
39
42
|
onChange?.(next);
|
|
40
43
|
};
|
|
41
44
|
const containerRef = useRef(null);
|
|
45
|
+
const triggerRef = useRef(null);
|
|
46
|
+
const panelRef = useRef(null);
|
|
42
47
|
const mouseX = useMotionValue(0);
|
|
43
48
|
const mouseY = useMotionValue(0);
|
|
44
49
|
const radius = 100;
|
|
50
|
+
const [panelPosition, setPanelPosition] = useState({
|
|
51
|
+
top: 0,
|
|
52
|
+
left: 0,
|
|
53
|
+
minWidth: 320
|
|
54
|
+
});
|
|
45
55
|
useEffect(() => {
|
|
46
|
-
const
|
|
47
|
-
|
|
56
|
+
const isEventInside = (event) => {
|
|
57
|
+
return (typeof event.composedPath === "function" ? event.composedPath() : []).some((target) => {
|
|
58
|
+
if (!(target instanceof Node)) return false;
|
|
59
|
+
return containerRef.current?.contains(target) || panelRef.current?.contains(target);
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
const handlePointerOutside = (event) => {
|
|
63
|
+
const target = event.target;
|
|
64
|
+
if (target instanceof Node && (containerRef.current?.contains(target) || panelRef.current?.contains(target)) || isEventInside(event)) return;
|
|
65
|
+
setOpen(false);
|
|
66
|
+
};
|
|
67
|
+
const handleFocusOutside = (event) => {
|
|
68
|
+
const target = event.target;
|
|
69
|
+
if (target instanceof Node && (containerRef.current?.contains(target) || panelRef.current?.contains(target)) || isEventInside(event)) return;
|
|
70
|
+
setOpen(false);
|
|
48
71
|
};
|
|
49
|
-
if (open)
|
|
72
|
+
if (open) {
|
|
73
|
+
document.addEventListener("pointerdown", handlePointerOutside, true);
|
|
74
|
+
document.addEventListener("focusin", handleFocusOutside, true);
|
|
75
|
+
}
|
|
50
76
|
return () => {
|
|
51
|
-
document.removeEventListener("
|
|
77
|
+
document.removeEventListener("pointerdown", handlePointerOutside, true);
|
|
78
|
+
document.removeEventListener("focusin", handleFocusOutside, true);
|
|
52
79
|
};
|
|
53
80
|
}, [open]);
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
if (!open) return;
|
|
83
|
+
const updatePanelPosition = () => {
|
|
84
|
+
const triggerRect = triggerRef.current?.getBoundingClientRect();
|
|
85
|
+
if (!triggerRect) return;
|
|
86
|
+
const panelHeight = panelRef.current?.offsetHeight ?? 360;
|
|
87
|
+
const shouldOpenAbove = window.innerHeight - triggerRect.bottom < panelHeight + PANEL_GAP && triggerRect.top > panelHeight + PANEL_GAP;
|
|
88
|
+
const unclampedLeft = triggerRect.left;
|
|
89
|
+
const maxLeft = Math.max(VIEWPORT_MARGIN, window.innerWidth - Math.max(triggerRect.width, 320) - VIEWPORT_MARGIN);
|
|
90
|
+
const left = Math.min(Math.max(unclampedLeft, VIEWPORT_MARGIN), maxLeft);
|
|
91
|
+
setPanelPosition({
|
|
92
|
+
top: shouldOpenAbove ? Math.max(VIEWPORT_MARGIN, triggerRect.top - panelHeight - PANEL_GAP) : Math.min(triggerRect.bottom + PANEL_GAP, window.innerHeight - panelHeight - VIEWPORT_MARGIN),
|
|
93
|
+
left,
|
|
94
|
+
minWidth: Math.max(triggerRect.width, 320)
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
updatePanelPosition();
|
|
98
|
+
const frameId = window.requestAnimationFrame(updatePanelPosition);
|
|
99
|
+
window.addEventListener("resize", updatePanelPosition);
|
|
100
|
+
window.addEventListener("scroll", updatePanelPosition, true);
|
|
101
|
+
return () => {
|
|
102
|
+
window.cancelAnimationFrame(frameId);
|
|
103
|
+
window.removeEventListener("resize", updatePanelPosition);
|
|
104
|
+
window.removeEventListener("scroll", updatePanelPosition, true);
|
|
105
|
+
};
|
|
106
|
+
}, [open, presets]);
|
|
54
107
|
const handleMouseMove = (event) => {
|
|
55
108
|
const { left, top } = event.currentTarget.getBoundingClientRect();
|
|
56
109
|
mouseX.set(event.clientX - left);
|
|
@@ -68,9 +121,9 @@ var DatePicker = ({ mode = "single", value, onChange, label, placeholder = "Pick
|
|
|
68
121
|
className: "text-sm font-medium text-heading",
|
|
69
122
|
children: label
|
|
70
123
|
}),
|
|
71
|
-
/* @__PURE__ */
|
|
124
|
+
/* @__PURE__ */ jsx("div", {
|
|
72
125
|
className: "relative",
|
|
73
|
-
children:
|
|
126
|
+
children: /* @__PURE__ */ jsx(motion.div, {
|
|
74
127
|
style: { backgroundImage: disabled ? "none" : useMotionTemplate`
|
|
75
128
|
radial-gradient(
|
|
76
129
|
${visible ? `${radius}px` : "0px"} circle at ${mouseX}px ${mouseY}px,
|
|
@@ -83,8 +136,9 @@ var DatePicker = ({ mode = "single", value, onChange, label, placeholder = "Pick
|
|
|
83
136
|
onMouseLeave: !disabled ? () => setVisible(false) : void 0,
|
|
84
137
|
className: disabled ? "group/date-picker rounded-lg border-none bg-muted p-[2px]" : "group/date-picker rounded-lg border-border p-[2px]",
|
|
85
138
|
children: /* @__PURE__ */ jsxs("button", {
|
|
139
|
+
ref: triggerRef,
|
|
86
140
|
type: "button",
|
|
87
|
-
className: `
|
|
141
|
+
className: `flex w-full items-center justify-between rounded-md border border-input bg-background-secondary px-3 py-2 text-sm text-foreground transition duration-400 ease-in-out ${disabled ? "cursor-not-allowed opacity-50" : ""}`,
|
|
88
142
|
onClick: () => !disabled && setOpen((prev) => !prev),
|
|
89
143
|
"aria-haspopup": "dialog",
|
|
90
144
|
"aria-expanded": open,
|
|
@@ -97,8 +151,28 @@ var DatePicker = ({ mode = "single", value, onChange, label, placeholder = "Pick
|
|
|
97
151
|
children: "📅"
|
|
98
152
|
})]
|
|
99
153
|
})
|
|
100
|
-
})
|
|
101
|
-
|
|
154
|
+
})
|
|
155
|
+
}),
|
|
156
|
+
helperText && /* @__PURE__ */ jsx("p", {
|
|
157
|
+
className: "text-xs text-muted-foreground",
|
|
158
|
+
children: helperText
|
|
159
|
+
}),
|
|
160
|
+
open && !disabled && typeof document !== "undefined" ? createPortal(/* @__PURE__ */ jsxs("div", {
|
|
161
|
+
className: "fixed inset-0 z-60",
|
|
162
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
163
|
+
className: "absolute inset-0",
|
|
164
|
+
"aria-hidden": "true",
|
|
165
|
+
onPointerDown: () => setOpen(false)
|
|
166
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
167
|
+
ref: panelRef,
|
|
168
|
+
className: "dropdown-panel absolute z-10",
|
|
169
|
+
style: {
|
|
170
|
+
top: panelPosition.top,
|
|
171
|
+
left: panelPosition.left,
|
|
172
|
+
minWidth: panelPosition.minWidth
|
|
173
|
+
},
|
|
174
|
+
role: "dialog",
|
|
175
|
+
"aria-modal": "false",
|
|
102
176
|
children: [/* @__PURE__ */ jsx(Calendar, {
|
|
103
177
|
value: mode === "single" ? singleValue ?? null : void 0,
|
|
104
178
|
selectionMode: mode,
|
|
@@ -112,7 +186,7 @@ var DatePicker = ({ mode = "single", value, onChange, label, placeholder = "Pick
|
|
|
112
186
|
if (nextRange.start && nextRange.end) setOpen(false);
|
|
113
187
|
} : void 0
|
|
114
188
|
}), presets?.length ? /* @__PURE__ */ jsx("div", {
|
|
115
|
-
className: "mt-3 flex flex-wrap gap-2",
|
|
189
|
+
className: "mt-3 flex flex-wrap gap-2 rounded-lg border border-white/20 bg-white/70 p-3 shadow-xl backdrop-blur-xl dark:border-white/10 dark:bg-neutral-900/70",
|
|
116
190
|
children: presets.map((preset) => /* @__PURE__ */ jsx("button", {
|
|
117
191
|
type: "button",
|
|
118
192
|
className: "rounded-full border border-input px-3 py-1 text-xs text-muted-foreground transition-colors hover:border-accent hover:bg-accent-subtle hover:text-accent",
|
|
@@ -121,15 +195,11 @@ var DatePicker = ({ mode = "single", value, onChange, label, placeholder = "Pick
|
|
|
121
195
|
}, preset.label))
|
|
122
196
|
}) : null]
|
|
123
197
|
})]
|
|
124
|
-
}),
|
|
125
|
-
helperText && /* @__PURE__ */ jsx("p", {
|
|
126
|
-
className: "text-xs text-muted-foreground",
|
|
127
|
-
children: helperText
|
|
128
|
-
})
|
|
198
|
+
}), document.body) : null
|
|
129
199
|
]
|
|
130
200
|
});
|
|
131
201
|
};
|
|
132
202
|
//#endregion
|
|
133
203
|
export { DatePicker as t };
|
|
134
204
|
|
|
135
|
-
//# sourceMappingURL=date-picker-
|
|
205
|
+
//# sourceMappingURL=date-picker-CNPORxhv.mjs.map
|