@akshar-technosoft/ui 1.3.1 → 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -0
- package/dist/components/core/error.cjs +3 -0
- package/dist/components/core/error.cjs.map +1 -0
- package/dist/components/core/error.d.cts +5 -0
- package/dist/components/core/error.d.ts +5 -0
- package/dist/components/core/error.js +3 -0
- package/dist/components/core/error.js.map +1 -0
- package/dist/components/core/event-success.cjs +3 -0
- package/dist/components/core/event-success.cjs.map +1 -0
- package/dist/components/core/event-success.d.cts +5 -0
- package/dist/components/core/event-success.d.ts +5 -0
- package/dist/components/core/event-success.js +3 -0
- package/dist/components/core/event-success.js.map +1 -0
- package/dist/components/core/index.cjs +3 -0
- package/dist/components/core/index.cjs.map +1 -0
- package/dist/components/core/index.d.cts +7 -0
- package/dist/components/core/index.d.ts +7 -0
- package/dist/components/core/index.js +3 -0
- package/dist/components/core/index.js.map +1 -0
- package/dist/components/core/loader.cjs +3 -0
- package/dist/components/core/loader.cjs.map +1 -0
- package/dist/components/core/loader.d.cts +5 -0
- package/dist/components/core/loader.d.ts +5 -0
- package/dist/components/core/loader.js +3 -0
- package/dist/components/core/loader.js.map +1 -0
- package/dist/components/core/notfound.cjs +3 -0
- package/dist/components/core/notfound.cjs.map +1 -0
- package/dist/components/core/notfound.d.cts +5 -0
- package/dist/components/core/notfound.d.ts +5 -0
- package/dist/components/core/notfound.js +3 -0
- package/dist/components/core/notfound.js.map +1 -0
- package/dist/components/core/offline-content.cjs +3 -0
- package/dist/components/core/offline-content.cjs.map +1 -0
- package/dist/components/core/offline-content.d.cts +5 -0
- package/dist/components/core/offline-content.d.ts +5 -0
- package/dist/components/core/offline-content.js +3 -0
- package/dist/components/core/offline-content.js.map +1 -0
- package/dist/components/core/unauthorized.cjs +3 -0
- package/dist/components/core/unauthorized.cjs.map +1 -0
- package/dist/components/core/unauthorized.d.cts +5 -0
- package/dist/components/core/unauthorized.d.ts +5 -0
- package/dist/components/core/unauthorized.js +3 -0
- package/dist/components/core/unauthorized.js.map +1 -0
- package/dist/components/data/data-table/data-table-action-bar.cjs +3 -0
- package/dist/components/data/data-table/data-table-action-bar.cjs.map +1 -0
- package/dist/components/data/data-table/data-table-action-bar.d.cts +26 -0
- package/dist/components/data/data-table/data-table-action-bar.d.ts +26 -0
- package/dist/components/data/data-table/data-table-action-bar.js +3 -0
- package/dist/components/data/data-table/data-table-action-bar.js.map +1 -0
- package/dist/components/data/data-table/data-table-aggregation.cjs +3 -0
- package/dist/components/data/data-table/data-table-aggregation.cjs.map +1 -0
- package/dist/components/data/data-table/data-table-aggregation.d.cts +25 -0
- package/dist/components/data/data-table/data-table-aggregation.d.ts +25 -0
- package/dist/components/data/data-table/data-table-aggregation.js +3 -0
- package/dist/components/data/data-table/data-table-aggregation.js.map +1 -0
- package/dist/components/data/data-table/data-table-columns.cjs +3 -0
- package/dist/components/data/data-table/data-table-columns.cjs.map +1 -0
- package/dist/components/data/data-table/data-table-columns.d.cts +20 -0
- package/dist/components/data/data-table/data-table-columns.d.ts +20 -0
- package/dist/components/data/data-table/data-table-columns.js +3 -0
- package/dist/components/data/data-table/data-table-columns.js.map +1 -0
- package/dist/components/data/data-table/data-table-export.cjs +3 -0
- package/dist/components/data/data-table/data-table-export.cjs.map +1 -0
- package/dist/components/data/data-table/data-table-export.d.cts +38 -0
- package/dist/components/data/data-table/data-table-export.d.ts +38 -0
- package/dist/components/data/data-table/data-table-export.js +3 -0
- package/dist/components/data/data-table/data-table-export.js.map +1 -0
- package/dist/components/data/data-table/data-table-filtering.cjs +3 -0
- package/dist/components/data/data-table/data-table-filtering.cjs.map +1 -0
- package/dist/components/data/data-table/data-table-filtering.d.cts +17 -0
- package/dist/components/data/data-table/data-table-filtering.d.ts +17 -0
- package/dist/components/data/data-table/data-table-filtering.js +3 -0
- package/dist/components/data/data-table/data-table-filtering.js.map +1 -0
- package/dist/components/data/data-table/data-table-footer.cjs +3 -0
- package/dist/components/data/data-table/data-table-footer.cjs.map +1 -0
- package/dist/components/data/data-table/data-table-footer.d.cts +21 -0
- package/dist/components/data/data-table/data-table-footer.d.ts +21 -0
- package/dist/components/data/data-table/data-table-footer.js +3 -0
- package/dist/components/data/data-table/data-table-footer.js.map +1 -0
- package/dist/components/data/data-table/data-table-header.cjs +3 -0
- package/dist/components/data/data-table/data-table-header.cjs.map +1 -0
- package/dist/components/data/data-table/data-table-header.d.cts +23 -0
- package/dist/components/data/data-table/data-table-header.d.ts +23 -0
- package/dist/components/data/data-table/data-table-header.js +3 -0
- package/dist/components/data/data-table/data-table-header.js.map +1 -0
- package/dist/components/data/data-table/data-table-pagination.cjs +3 -0
- package/dist/components/data/data-table/data-table-pagination.cjs.map +1 -0
- package/dist/components/data/data-table/data-table-pagination.d.cts +14 -0
- package/dist/components/data/data-table/data-table-pagination.d.ts +14 -0
- package/dist/components/data/data-table/data-table-pagination.js +3 -0
- package/dist/components/data/data-table/data-table-pagination.js.map +1 -0
- package/dist/components/data/data-table/data-table-persist.cjs +3 -0
- package/dist/components/data/data-table/data-table-persist.cjs.map +1 -0
- package/dist/components/data/data-table/data-table-persist.d.cts +103 -0
- package/dist/components/data/data-table/data-table-persist.d.ts +103 -0
- package/dist/components/data/data-table/data-table-persist.js +3 -0
- package/dist/components/data/data-table/data-table-persist.js.map +1 -0
- package/dist/components/data/data-table/data-table-pinning.cjs +3 -0
- package/dist/components/data/data-table/data-table-pinning.cjs.map +1 -0
- package/dist/components/data/data-table/data-table-pinning.d.cts +39 -0
- package/dist/components/data/data-table/data-table-pinning.d.ts +39 -0
- package/dist/components/data/data-table/data-table-pinning.js +3 -0
- package/dist/components/data/data-table/data-table-pinning.js.map +1 -0
- package/dist/components/data/data-table/data-table-toolbar-menus.cjs +3 -0
- package/dist/components/data/data-table/data-table-toolbar-menus.cjs.map +1 -0
- package/dist/components/data/data-table/data-table-toolbar-menus.d.cts +21 -0
- package/dist/components/data/data-table/data-table-toolbar-menus.d.ts +21 -0
- package/dist/components/data/data-table/data-table-toolbar-menus.js +3 -0
- package/dist/components/data/data-table/data-table-toolbar-menus.js.map +1 -0
- package/dist/components/data/data-table/data-table-toolbar.cjs +3 -0
- package/dist/components/data/data-table/data-table-toolbar.cjs.map +1 -0
- package/dist/components/data/data-table/data-table-toolbar.d.cts +36 -0
- package/dist/components/data/data-table/data-table-toolbar.d.ts +36 -0
- package/dist/components/data/data-table/data-table-toolbar.js +3 -0
- package/dist/components/data/data-table/data-table-toolbar.js.map +1 -0
- package/dist/components/data/data-table/data-table-types.cjs +3 -0
- package/dist/components/data/data-table/data-table-types.cjs.map +1 -0
- package/dist/components/data/data-table/data-table-types.d.cts +536 -0
- package/dist/components/data/data-table/data-table-types.d.ts +536 -0
- package/dist/components/data/data-table/data-table-types.js +2 -0
- package/dist/components/data/data-table/data-table-types.js.map +1 -0
- package/dist/components/data/data-table/data-table.cjs +3 -0
- package/dist/components/data/data-table/data-table.cjs.map +1 -0
- package/dist/components/data/data-table/data-table.d.cts +10 -0
- package/dist/components/data/data-table/data-table.d.ts +10 -0
- package/dist/components/data/data-table/data-table.js +3 -0
- package/dist/components/data/data-table/data-table.js.map +1 -0
- package/dist/components/data/data-table/index.cjs +3 -0
- package/dist/components/data/data-table/index.cjs.map +1 -0
- package/dist/components/data/data-table/index.d.cts +16 -0
- package/dist/components/data/data-table/index.d.ts +16 -0
- package/dist/components/data/data-table/index.js +3 -0
- package/dist/components/data/data-table/index.js.map +1 -0
- package/dist/components/data/data-table/use-table-filter-param.cjs +3 -0
- package/dist/components/data/data-table/use-table-filter-param.cjs.map +1 -0
- package/dist/components/data/data-table/use-table-filter-param.d.cts +37 -0
- package/dist/components/data/data-table/use-table-filter-param.d.ts +37 -0
- package/dist/components/data/data-table/use-table-filter-param.js +3 -0
- package/dist/components/data/data-table/use-table-filter-param.js.map +1 -0
- package/dist/components/data/data-table/use-table-persist.cjs +3 -0
- package/dist/components/data/data-table/use-table-persist.cjs.map +1 -0
- package/dist/components/data/data-table/use-table-persist.d.cts +36 -0
- package/dist/components/data/data-table/use-table-persist.d.ts +36 -0
- package/dist/components/data/data-table/use-table-persist.js +3 -0
- package/dist/components/data/data-table/use-table-persist.js.map +1 -0
- package/dist/components/data/data-template/data-template-action-bar.cjs +3 -0
- package/dist/components/data/data-template/data-template-action-bar.cjs.map +1 -0
- package/dist/components/data/data-template/data-template-action-bar.d.cts +14 -0
- package/dist/components/data/data-template/data-template-action-bar.d.ts +14 -0
- package/dist/components/data/data-template/data-template-action-bar.js +3 -0
- package/dist/components/data/data-template/data-template-action-bar.js.map +1 -0
- package/dist/components/data/data-template/data-template-pagination.cjs +3 -0
- package/dist/components/data/data-template/data-template-pagination.cjs.map +1 -0
- package/dist/components/data/data-template/data-template-pagination.d.cts +17 -0
- package/dist/components/data/data-template/data-template-pagination.d.ts +17 -0
- package/dist/components/data/data-template/data-template-pagination.js +3 -0
- package/dist/components/data/data-template/data-template-pagination.js.map +1 -0
- package/dist/components/data/data-template/data-template-toolbar.cjs +3 -0
- package/dist/components/data/data-template/data-template-toolbar.cjs.map +1 -0
- package/dist/components/data/data-template/data-template-toolbar.d.cts +27 -0
- package/dist/components/data/data-template/data-template-toolbar.d.ts +27 -0
- package/dist/components/data/data-template/data-template-toolbar.js +3 -0
- package/dist/components/data/data-template/data-template-toolbar.js.map +1 -0
- package/dist/components/data/data-template/data-template-types.cjs +3 -0
- package/dist/components/data/data-template/data-template-types.cjs.map +1 -0
- package/dist/components/data/data-template/data-template-types.d.cts +105 -0
- package/dist/components/data/data-template/data-template-types.d.ts +105 -0
- package/dist/components/data/data-template/data-template-types.js +2 -0
- package/dist/components/data/data-template/data-template-types.js.map +1 -0
- package/dist/components/data/data-template/data-template.cjs +3 -0
- package/dist/components/data/data-template/data-template.cjs.map +1 -0
- package/dist/components/data/data-template/data-template.d.cts +8 -0
- package/dist/components/data/data-template/data-template.d.ts +8 -0
- package/dist/components/data/data-template/data-template.js +3 -0
- package/dist/components/data/data-template/data-template.js.map +1 -0
- package/dist/components/data/data-template/index.cjs +3 -0
- package/dist/components/data/data-template/index.cjs.map +1 -0
- package/dist/components/data/data-template/index.d.cts +8 -0
- package/dist/components/data/data-template/index.d.ts +8 -0
- package/dist/components/data/data-template/index.js +3 -0
- package/dist/components/data/data-template/index.js.map +1 -0
- package/dist/components/date-helper.cjs +0 -0
- package/dist/components/date-helper.cjs.map +0 -0
- package/dist/components/date-helper.d.cts +0 -0
- package/dist/components/date-helper.d.ts +0 -0
- package/dist/components/date-helper.js +0 -0
- package/dist/components/date-helper.js.map +0 -0
- package/dist/components/general.cjs +0 -0
- package/dist/components/general.cjs.map +0 -0
- package/dist/components/general.d.cts +0 -0
- package/dist/components/general.d.ts +0 -0
- package/dist/components/general.js +0 -0
- package/dist/components/general.js.map +0 -0
- package/dist/components/helper/date-filter.cjs +3 -0
- package/dist/components/helper/date-filter.cjs.map +1 -0
- package/dist/components/helper/date-filter.d.cts +19 -0
- package/dist/components/helper/date-filter.d.ts +19 -0
- package/dist/components/helper/date-filter.js +3 -0
- package/dist/components/helper/date-filter.js.map +1 -0
- package/dist/components/layouts/app-container.cjs +3 -0
- package/dist/components/layouts/app-container.cjs.map +1 -0
- package/dist/components/layouts/app-container.d.cts +11 -0
- package/dist/components/layouts/app-container.d.ts +11 -0
- package/dist/components/layouts/app-container.js +3 -0
- package/dist/components/layouts/app-container.js.map +1 -0
- package/dist/components/layouts/app-content.cjs +3 -0
- package/dist/components/layouts/app-content.cjs.map +1 -0
- package/dist/components/layouts/app-content.d.cts +53 -0
- package/dist/components/layouts/app-content.d.ts +53 -0
- package/dist/components/layouts/app-content.js +3 -0
- package/dist/components/layouts/app-content.js.map +1 -0
- package/dist/components/layouts/app-footer.cjs +3 -0
- package/dist/components/layouts/app-footer.cjs.map +1 -0
- package/dist/components/layouts/app-footer.d.cts +17 -0
- package/dist/components/layouts/app-footer.d.ts +17 -0
- package/dist/components/layouts/app-footer.js +3 -0
- package/dist/components/layouts/app-footer.js.map +1 -0
- package/dist/components/layouts/app-header.cjs +3 -0
- package/dist/components/layouts/app-header.cjs.map +1 -0
- package/dist/components/layouts/app-header.d.cts +32 -0
- package/dist/components/layouts/app-header.d.ts +32 -0
- package/dist/components/layouts/app-header.js +3 -0
- package/dist/components/layouts/app-header.js.map +1 -0
- package/dist/components/layouts/index.cjs +3 -0
- package/dist/components/layouts/index.cjs.map +1 -0
- package/dist/components/layouts/index.d.cts +7 -0
- package/dist/components/layouts/index.d.ts +7 -0
- package/dist/components/layouts/index.js +3 -0
- package/dist/components/layouts/index.js.map +1 -0
- package/dist/components/ui/badge.cjs +3 -0
- package/dist/components/ui/badge.cjs.map +1 -0
- package/dist/components/ui/badge.d.cts +13 -0
- package/dist/components/ui/badge.d.ts +13 -0
- package/dist/components/ui/badge.js +3 -0
- package/dist/components/ui/badge.js.map +1 -0
- package/dist/components/ui/button.cjs +3 -0
- package/dist/components/ui/button.cjs.map +1 -0
- package/dist/components/ui/button.d.cts +14 -0
- package/dist/components/ui/button.d.ts +14 -0
- package/dist/components/ui/button.js +3 -0
- package/dist/components/ui/button.js.map +1 -0
- package/dist/components/ui/calendar.cjs +3 -0
- package/dist/components/ui/calendar.cjs.map +1 -0
- package/dist/components/ui/calendar.d.cts +13 -0
- package/dist/components/ui/calendar.d.ts +13 -0
- package/dist/components/ui/calendar.js +3 -0
- package/dist/components/ui/calendar.js.map +1 -0
- package/dist/components/ui/card.cjs +3 -0
- package/dist/components/ui/card.cjs.map +1 -0
- package/dist/components/ui/card.d.cts +12 -0
- package/dist/components/ui/card.d.ts +12 -0
- package/dist/components/ui/card.js +3 -0
- package/dist/components/ui/card.js.map +1 -0
- package/dist/components/ui/checkbox.cjs +3 -0
- package/dist/components/ui/checkbox.cjs.map +1 -0
- package/dist/components/ui/checkbox.d.cts +7 -0
- package/dist/components/ui/checkbox.d.ts +7 -0
- package/dist/components/ui/checkbox.js +3 -0
- package/dist/components/ui/checkbox.js.map +1 -0
- package/dist/components/ui/command.cjs +3 -0
- package/dist/components/ui/command.cjs.map +1 -0
- package/dist/components/ui/command.d.cts +20 -0
- package/dist/components/ui/command.d.ts +20 -0
- package/dist/components/ui/command.js +3 -0
- package/dist/components/ui/command.js.map +1 -0
- package/dist/components/ui/dialog.cjs +3 -0
- package/dist/components/ui/dialog.cjs.map +1 -0
- package/dist/components/ui/dialog.d.cts +16 -0
- package/dist/components/ui/dialog.d.ts +16 -0
- package/dist/components/ui/dialog.js +3 -0
- package/dist/components/ui/dialog.js.map +1 -0
- package/dist/components/ui/dropdown-menu.cjs +3 -0
- package/dist/components/ui/dropdown-menu.cjs.map +1 -0
- package/dist/components/ui/dropdown-menu.d.cts +28 -0
- package/dist/components/ui/dropdown-menu.d.ts +28 -0
- package/dist/components/ui/dropdown-menu.js +3 -0
- package/dist/components/ui/dropdown-menu.js.map +1 -0
- package/dist/components/ui/input.cjs +3 -0
- package/dist/components/ui/input.cjs.map +1 -0
- package/dist/components/ui/input.d.cts +6 -0
- package/dist/components/ui/input.d.ts +6 -0
- package/dist/components/ui/input.js +3 -0
- package/dist/components/ui/input.js.map +1 -0
- package/dist/components/ui/popover.cjs +3 -0
- package/dist/components/ui/popover.cjs.map +1 -0
- package/dist/components/ui/popover.d.cts +10 -0
- package/dist/components/ui/popover.d.ts +10 -0
- package/dist/components/ui/popover.js +3 -0
- package/dist/components/ui/popover.js.map +1 -0
- package/dist/components/ui/select.cjs +3 -0
- package/dist/components/ui/select.cjs.map +1 -0
- package/dist/components/ui/select.d.cts +18 -0
- package/dist/components/ui/select.d.ts +18 -0
- package/dist/components/ui/select.js +3 -0
- package/dist/components/ui/select.js.map +1 -0
- package/dist/components/ui/separator.cjs +3 -0
- package/dist/components/ui/separator.cjs.map +1 -0
- package/dist/components/ui/separator.d.cts +7 -0
- package/dist/components/ui/separator.d.ts +7 -0
- package/dist/components/ui/separator.js +3 -0
- package/dist/components/ui/separator.js.map +1 -0
- package/dist/components/ui/sheet.cjs +3 -0
- package/dist/components/ui/sheet.cjs.map +1 -0
- package/dist/components/ui/sheet.d.cts +18 -0
- package/dist/components/ui/sheet.d.ts +18 -0
- package/dist/components/ui/sheet.js +3 -0
- package/dist/components/ui/sheet.js.map +1 -0
- package/dist/components/ui/table.cjs +3 -0
- package/dist/components/ui/table.cjs.map +1 -0
- package/dist/components/ui/table.d.cts +13 -0
- package/dist/components/ui/table.d.ts +13 -0
- package/dist/components/ui/table.js +3 -0
- package/dist/components/ui/table.js.map +1 -0
- package/dist/components/ui/toggle.cjs +3 -0
- package/dist/components/ui/toggle.cjs.map +1 -0
- package/dist/components/ui/toggle.d.cts +16 -0
- package/dist/components/ui/toggle.d.ts +16 -0
- package/dist/components/ui/toggle.js +3 -0
- package/dist/components/ui/toggle.js.map +1 -0
- package/dist/components/ui/tooltip.cjs +3 -0
- package/dist/components/ui/tooltip.cjs.map +1 -0
- package/dist/components/ui/tooltip.d.cts +10 -0
- package/dist/components/ui/tooltip.d.ts +10 -0
- package/dist/components/ui/tooltip.js +3 -0
- package/dist/components/ui/tooltip.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +28 -920
- package/dist/index.d.ts +28 -920
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/utils.cjs +0 -0
- package/dist/lib/utils.cjs.map +0 -0
- package/dist/lib/utils.d.cts +0 -0
- package/dist/lib/utils.d.ts +0 -0
- package/dist/lib/utils.js +0 -0
- package/dist/lib/utils.js.map +0 -0
- package/package.json +92 -92
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Table } from '@tanstack/react-table';
|
|
2
|
+
|
|
3
|
+
type TableExportColumn = {
|
|
4
|
+
/** The column's id (accessorKey for accessor columns). */
|
|
5
|
+
id: string;
|
|
6
|
+
/** Header text: `exportHeader` if given, else the string `header`, else the id. */
|
|
7
|
+
header: string;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* A plain, file-format-agnostic snapshot of what the table is currently showing: the visible
|
|
11
|
+
* columns in display order and every row that survives the active filters and sorting (all pages,
|
|
12
|
+
* not just the one on screen). Hand it to an app-side writer (Excel, CSV, print) — the table never
|
|
13
|
+
* touches file generation itself, so the component stays free of heavy spreadsheet dependencies.
|
|
14
|
+
*/
|
|
15
|
+
type TableExportView<TData = unknown> = {
|
|
16
|
+
columns: TableExportColumn[];
|
|
17
|
+
/** One array per row, cell values in `columns` order. Values keep their native type (number,
|
|
18
|
+
* Date, boolean…) so the writer can apply proper cell formatting instead of dumping strings. */
|
|
19
|
+
rows: unknown[][];
|
|
20
|
+
/** The filtered + sorted row originals, same order as `rows`, for writers that want raw data. */
|
|
21
|
+
originals: TData[];
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Build a {@link TableExportView} from the table's CURRENT state, exactly as the user shaped it:
|
|
25
|
+
* hidden columns are skipped, column order (including pinning) is respected, and rows come from the
|
|
26
|
+
* pre-pagination model, so they are filtered and sorted but not cut to the visible page.
|
|
27
|
+
*
|
|
28
|
+
* Which columns make it in: a visible column is exported when it has an accessor (accessorKey or
|
|
29
|
+
* accessorFn) or a `exportValue` on its def. Display-only columns (actions, JSX-composed cells
|
|
30
|
+
* without an accessor) are skipped unless they provide `exportValue`. A JSX `header` falls back to
|
|
31
|
+
* the column id unless `exportHeader` names it.
|
|
32
|
+
*
|
|
33
|
+
* Call it anywhere you hold the table instance (from `onTableReady` or the `children` render prop);
|
|
34
|
+
* the toolbar's Export button calls it for you and passes the result to `onExport`.
|
|
35
|
+
*/
|
|
36
|
+
declare function getTableExportView<TData>(table: Table<TData>): TableExportView<TData>;
|
|
37
|
+
|
|
38
|
+
export { type TableExportColumn, type TableExportView, getTableExportView };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
var s=new Set(["select","serialNumber"]);function i(t){let r=t.getVisibleLeafColumns().filter(e=>s.has(e.id)?!1:!!e.columnDef.exportValue||!!e.accessorFn),o=t.getPrePaginationRowModel().rows;return{columns:r.map(e=>{let a=e.columnDef;return{id:e.id,header:a.exportHeader??(typeof a.header=="string"?a.header:e.id)}}),rows:o.map(e=>r.map(a=>{let n=a.columnDef;return n.exportValue?n.exportValue(e.original):e.getValue(a.id)})),originals:o.map(e=>e.original)}}export{i as getTableExportView};
|
|
3
|
+
//# sourceMappingURL=data-table-export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/data/data-table/data-table-export.ts"],"sourcesContent":["import type { Table } from \"@tanstack/react-table\"\nimport type { GroupColumnDef } from \"./data-table-types.js\"\n\nexport type TableExportColumn = {\n /** The column's id (accessorKey for accessor columns). */\n id: string\n /** Header text: `exportHeader` if given, else the string `header`, else the id. */\n header: string\n}\n\n/**\n * A plain, file-format-agnostic snapshot of what the table is currently showing: the visible\n * columns in display order and every row that survives the active filters and sorting (all pages,\n * not just the one on screen). Hand it to an app-side writer (Excel, CSV, print) — the table never\n * touches file generation itself, so the component stays free of heavy spreadsheet dependencies.\n */\nexport type TableExportView<TData = unknown> = {\n columns: TableExportColumn[]\n /** One array per row, cell values in `columns` order. Values keep their native type (number,\n * Date, boolean…) so the writer can apply proper cell formatting instead of dumping strings. */\n rows: unknown[][]\n /** The filtered + sorted row originals, same order as `rows`, for writers that want raw data. */\n originals: TData[]\n}\n\n// Internal helper columns that never belong in an export.\nconst HELPER_COLUMN_IDS = new Set([\"select\", \"serialNumber\"])\n\n/**\n * Build a {@link TableExportView} from the table's CURRENT state, exactly as the user shaped it:\n * hidden columns are skipped, column order (including pinning) is respected, and rows come from the\n * pre-pagination model, so they are filtered and sorted but not cut to the visible page.\n *\n * Which columns make it in: a visible column is exported when it has an accessor (accessorKey or\n * accessorFn) or a `exportValue` on its def. Display-only columns (actions, JSX-composed cells\n * without an accessor) are skipped unless they provide `exportValue`. A JSX `header` falls back to\n * the column id unless `exportHeader` names it.\n *\n * Call it anywhere you hold the table instance (from `onTableReady` or the `children` render prop);\n * the toolbar's Export button calls it for you and passes the result to `onExport`.\n */\nexport function getTableExportView<TData>(table: Table<TData>): TableExportView<TData> {\n const columns = table.getVisibleLeafColumns().filter((col) => {\n if (HELPER_COLUMN_IDS.has(col.id)) return false\n const def = col.columnDef as GroupColumnDef<TData>\n return !!def.exportValue || !!col.accessorFn\n })\n const rows = table.getPrePaginationRowModel().rows\n\n return {\n columns: columns.map((col) => {\n const def = col.columnDef as GroupColumnDef<TData>\n return {\n id: col.id,\n header: def.exportHeader ?? (typeof def.header === \"string\" ? def.header : col.id),\n }\n }),\n rows: rows.map((row) =>\n columns.map((col) => {\n const def = col.columnDef as GroupColumnDef<TData>\n return def.exportValue ? def.exportValue(row.original) : row.getValue(col.id)\n })\n ),\n originals: rows.map((row) => row.original),\n }\n}\n"],"mappings":";AA0BA,IAAMA,EAAoB,IAAI,IAAI,CAAC,SAAU,cAAc,CAAC,EAerD,SAASC,EAA0BC,EAA6C,CACrF,IAAMC,EAAUD,EAAM,sBAAsB,EAAE,OAAQE,GAChDJ,EAAkB,IAAII,EAAI,EAAE,EAAU,GAEnC,CAAC,CADIA,EAAI,UACH,aAAe,CAAC,CAACA,EAAI,UACnC,EACKC,EAAOH,EAAM,yBAAyB,EAAE,KAE9C,MAAO,CACL,QAASC,EAAQ,IAAKC,GAAQ,CAC5B,IAAME,EAAMF,EAAI,UAChB,MAAO,CACL,GAAIA,EAAI,GACR,OAAQE,EAAI,eAAiB,OAAOA,EAAI,QAAW,SAAWA,EAAI,OAASF,EAAI,GACjF,CACF,CAAC,EACD,KAAMC,EAAK,IAAKE,GACdJ,EAAQ,IAAKC,GAAQ,CACnB,IAAME,EAAMF,EAAI,UAChB,OAAOE,EAAI,YAAcA,EAAI,YAAYC,EAAI,QAAQ,EAAIA,EAAI,SAASH,EAAI,EAAE,CAC9E,CAAC,CACH,EACA,UAAWC,EAAK,IAAKE,GAAQA,EAAI,QAAQ,CAC3C,CACF","names":["HELPER_COLUMN_IDS","getTableExportView","table","columns","col","rows","def","row"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
"use strict";var r=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var m=Object.prototype.hasOwnProperty;var p=(t,n)=>{for(var e in n)r(t,e,{get:n[e],enumerable:!0})},C=(t,n,e,i)=>{if(n&&typeof n=="object"||typeof n=="function")for(let o of g(n))!m.call(t,o)&&o!==e&&r(t,o,{get:()=>n[o],enumerable:!(i=d(n,o))||i.enumerable});return t};var F=t=>C(r({},"__esModule",{value:!0}),t);var b={};p(b,{buildFilterOnlyColumns:()=>T,getNestedValue:()=>f});module.exports=F(b);function f(t,n){return n.split(".").reduce((e,i)=>e&&e[i],t)}function y(t,n=new Set){for(let e of t){let i=e.id??e.accessorKey;i&&n.add(String(i)),e.columns&&y(e.columns,n)}return n}function T(t,n){let e=y(t),i=[];for(let o of n){if(o.externalSearch)continue;let l=typeof o.filterFn=="function",s=l?o.id:o.key;if(!s||e.has(String(s)))continue;let u=o.key;i.push({id:String(s),accessorFn:u?a=>f(a,u):()=>null,...l&&{filterFn:(a,G,c)=>o.filterFn(a.original,c)},enableHiding:!1,enableSorting:!1,enablePinning:!1,enableGlobalFilter:!1,meta:{filterOnly:!0}})}return i}0&&(module.exports={buildFilterOnlyColumns,getNestedValue});
|
|
3
|
+
//# sourceMappingURL=data-table-filtering.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/data/data-table/data-table-filtering.ts"],"sourcesContent":["import type { FilterConfig, GroupColumnDef } from \"./data-table-types.js\"\n\n/** Read a nested value by dot-path, e.g. `getNestedValue(row, \"party.name\")`. */\nexport function getNestedValue(obj: any, path: string) {\n return path.split(\".\").reduce((acc, part) => acc && acc[part], obj)\n}\n\n/** Every column id/accessorKey already declared (recursing into group columns). */\nfunction collectColumnIds<T>(cols: GroupColumnDef<T>[], acc = new Set<string>()): Set<string> {\n for (const c of cols) {\n const id = (c as any).id ?? (c as any).accessorKey\n if (id) acc.add(String(id))\n if ((c as any).columns) collectColumnIds((c as any).columns, acc)\n }\n return acc\n}\n\n/**\n * Auto-generate hidden, filter-only columns from the `filters` array, so a filter can target a field\n * that has no visible column or run custom `filterFn` logic (arrays / multi-field), without the\n * consumer touching `columns`. Skips filters that already map to a real column, and external\n * (server) filters. The columns never render and stay out of global search.\n */\nexport function buildFilterOnlyColumns<T>(\n initialColumns: GroupColumnDef<T>[],\n filters: FilterConfig<T>[],\n): GroupColumnDef<T>[] {\n const existing = collectColumnIds(initialColumns)\n const out: GroupColumnDef<T>[] = []\n for (const f of filters) {\n if (f.externalSearch) continue\n const custom = typeof (f as any).filterFn === \"function\"\n const id = custom ? (f as any).id : (f as any).key\n if (!id || existing.has(String(id))) continue\n const key = (f as any).key as string | undefined\n out.push({\n id: String(id),\n accessorFn: key ? (r: any) => getNestedValue(r, key) : () => null,\n // Spread with an explicit `filterFn: undefined` would overwrite TanStack's default 'auto'\n // and kill the filter entirely, so the key is only present for custom filters.\n ...(custom && { filterFn: (row: any, _id: string, value: any) => (f as any).filterFn(row.original, value) }),\n enableHiding: false,\n enableSorting: false,\n enablePinning: false,\n enableGlobalFilter: false,\n meta: { filterOnly: true },\n } as GroupColumnDef<T>)\n }\n return out\n}\n"],"mappings":";yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,4BAAAE,EAAA,mBAAAC,IAAA,eAAAC,EAAAJ,GAGO,SAASG,EAAeE,EAAUC,EAAc,CACrD,OAAOA,EAAK,MAAM,GAAG,EAAE,OAAO,CAACC,EAAKC,IAASD,GAAOA,EAAIC,CAAI,EAAGH,CAAG,CACpE,CAGA,SAASI,EAAoBC,EAA2BH,EAAM,IAAI,IAA4B,CAC5F,QAAWI,KAAKD,EAAM,CACpB,IAAME,EAAMD,EAAU,IAAOA,EAAU,YACnCC,GAAIL,EAAI,IAAI,OAAOK,CAAE,CAAC,EACrBD,EAAU,SAASF,EAAkBE,EAAU,QAASJ,CAAG,CAClE,CACA,OAAOA,CACT,CAQO,SAASL,EACdW,EACAC,EACqB,CACrB,IAAMC,EAAWN,EAAiBI,CAAc,EAC1CG,EAA2B,CAAC,EAClC,QAAWC,KAAKH,EAAS,CACvB,GAAIG,EAAE,eAAgB,SACtB,IAAMC,EAAS,OAAQD,EAAU,UAAa,WACxCL,EAAKM,EAAUD,EAAU,GAAMA,EAAU,IAC/C,GAAI,CAACL,GAAMG,EAAS,IAAI,OAAOH,CAAE,CAAC,EAAG,SACrC,IAAMO,EAAOF,EAAU,IACvBD,EAAI,KAAK,CACP,GAAI,OAAOJ,CAAE,EACb,WAAYO,EAAOC,GAAWjB,EAAeiB,EAAGD,CAAG,EAAI,IAAM,KAG7D,GAAID,GAAU,CAAE,SAAU,CAACG,EAAUC,EAAaC,IAAgBN,EAAU,SAASI,EAAI,SAAUE,CAAK,CAAE,EAC1G,aAAc,GACd,cAAe,GACf,cAAe,GACf,mBAAoB,GACpB,KAAM,CAAE,WAAY,EAAK,CAC3B,CAAsB,CACxB,CACA,OAAOP,CACT","names":["data_table_filtering_exports","__export","buildFilterOnlyColumns","getNestedValue","__toCommonJS","obj","path","acc","part","collectColumnIds","cols","c","id","initialColumns","filters","existing","out","f","custom","key","r","row","_id","value"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { GroupColumnDef, FilterConfig } from './data-table-types.cjs';
|
|
2
|
+
import '@tanstack/react-table';
|
|
3
|
+
import 'lucide-react';
|
|
4
|
+
import './data-table-persist.cjs';
|
|
5
|
+
import './data-table-export.cjs';
|
|
6
|
+
|
|
7
|
+
/** Read a nested value by dot-path, e.g. `getNestedValue(row, "party.name")`. */
|
|
8
|
+
declare function getNestedValue(obj: any, path: string): any;
|
|
9
|
+
/**
|
|
10
|
+
* Auto-generate hidden, filter-only columns from the `filters` array, so a filter can target a field
|
|
11
|
+
* that has no visible column or run custom `filterFn` logic (arrays / multi-field), without the
|
|
12
|
+
* consumer touching `columns`. Skips filters that already map to a real column, and external
|
|
13
|
+
* (server) filters. The columns never render and stay out of global search.
|
|
14
|
+
*/
|
|
15
|
+
declare function buildFilterOnlyColumns<T>(initialColumns: GroupColumnDef<T>[], filters: FilterConfig<T>[]): GroupColumnDef<T>[];
|
|
16
|
+
|
|
17
|
+
export { buildFilterOnlyColumns, getNestedValue };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { GroupColumnDef, FilterConfig } from './data-table-types.js';
|
|
2
|
+
import '@tanstack/react-table';
|
|
3
|
+
import 'lucide-react';
|
|
4
|
+
import './data-table-persist.js';
|
|
5
|
+
import './data-table-export.js';
|
|
6
|
+
|
|
7
|
+
/** Read a nested value by dot-path, e.g. `getNestedValue(row, "party.name")`. */
|
|
8
|
+
declare function getNestedValue(obj: any, path: string): any;
|
|
9
|
+
/**
|
|
10
|
+
* Auto-generate hidden, filter-only columns from the `filters` array, so a filter can target a field
|
|
11
|
+
* that has no visible column or run custom `filterFn` logic (arrays / multi-field), without the
|
|
12
|
+
* consumer touching `columns`. Skips filters that already map to a real column, and external
|
|
13
|
+
* (server) filters. The columns never render and stay out of global search.
|
|
14
|
+
*/
|
|
15
|
+
declare function buildFilterOnlyColumns<T>(initialColumns: GroupColumnDef<T>[], filters: FilterConfig<T>[]): GroupColumnDef<T>[];
|
|
16
|
+
|
|
17
|
+
export { buildFilterOnlyColumns, getNestedValue };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
function y(i,e){return e.split(".").reduce((n,t)=>n&&n[t],i)}function u(i,e=new Set){for(let n of i){let t=n.id??n.accessorKey;t&&e.add(String(t)),n.columns&&u(n.columns,e)}return e}function d(i,e){let n=u(i),t=[];for(let o of e){if(o.externalSearch)continue;let r=typeof o.filterFn=="function",s=r?o.id:o.key;if(!s||n.has(String(s)))continue;let l=o.key;t.push({id:String(s),accessorFn:l?a=>y(a,l):()=>null,...r&&{filterFn:(a,c,f)=>o.filterFn(a.original,f)},enableHiding:!1,enableSorting:!1,enablePinning:!1,enableGlobalFilter:!1,meta:{filterOnly:!0}})}return t}export{d as buildFilterOnlyColumns,y as getNestedValue};
|
|
3
|
+
//# sourceMappingURL=data-table-filtering.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/data/data-table/data-table-filtering.ts"],"sourcesContent":["import type { FilterConfig, GroupColumnDef } from \"./data-table-types.js\"\n\n/** Read a nested value by dot-path, e.g. `getNestedValue(row, \"party.name\")`. */\nexport function getNestedValue(obj: any, path: string) {\n return path.split(\".\").reduce((acc, part) => acc && acc[part], obj)\n}\n\n/** Every column id/accessorKey already declared (recursing into group columns). */\nfunction collectColumnIds<T>(cols: GroupColumnDef<T>[], acc = new Set<string>()): Set<string> {\n for (const c of cols) {\n const id = (c as any).id ?? (c as any).accessorKey\n if (id) acc.add(String(id))\n if ((c as any).columns) collectColumnIds((c as any).columns, acc)\n }\n return acc\n}\n\n/**\n * Auto-generate hidden, filter-only columns from the `filters` array, so a filter can target a field\n * that has no visible column or run custom `filterFn` logic (arrays / multi-field), without the\n * consumer touching `columns`. Skips filters that already map to a real column, and external\n * (server) filters. The columns never render and stay out of global search.\n */\nexport function buildFilterOnlyColumns<T>(\n initialColumns: GroupColumnDef<T>[],\n filters: FilterConfig<T>[],\n): GroupColumnDef<T>[] {\n const existing = collectColumnIds(initialColumns)\n const out: GroupColumnDef<T>[] = []\n for (const f of filters) {\n if (f.externalSearch) continue\n const custom = typeof (f as any).filterFn === \"function\"\n const id = custom ? (f as any).id : (f as any).key\n if (!id || existing.has(String(id))) continue\n const key = (f as any).key as string | undefined\n out.push({\n id: String(id),\n accessorFn: key ? (r: any) => getNestedValue(r, key) : () => null,\n // Spread with an explicit `filterFn: undefined` would overwrite TanStack's default 'auto'\n // and kill the filter entirely, so the key is only present for custom filters.\n ...(custom && { filterFn: (row: any, _id: string, value: any) => (f as any).filterFn(row.original, value) }),\n enableHiding: false,\n enableSorting: false,\n enablePinning: false,\n enableGlobalFilter: false,\n meta: { filterOnly: true },\n } as GroupColumnDef<T>)\n }\n return out\n}\n"],"mappings":";AAGO,SAASA,EAAeC,EAAUC,EAAc,CACrD,OAAOA,EAAK,MAAM,GAAG,EAAE,OAAO,CAACC,EAAKC,IAASD,GAAOA,EAAIC,CAAI,EAAGH,CAAG,CACpE,CAGA,SAASI,EAAoBC,EAA2BH,EAAM,IAAI,IAA4B,CAC5F,QAAWI,KAAKD,EAAM,CACpB,IAAME,EAAMD,EAAU,IAAOA,EAAU,YACnCC,GAAIL,EAAI,IAAI,OAAOK,CAAE,CAAC,EACrBD,EAAU,SAASF,EAAkBE,EAAU,QAASJ,CAAG,CAClE,CACA,OAAOA,CACT,CAQO,SAASM,EACdC,EACAC,EACqB,CACrB,IAAMC,EAAWP,EAAiBK,CAAc,EAC1CG,EAA2B,CAAC,EAClC,QAAWC,KAAKH,EAAS,CACvB,GAAIG,EAAE,eAAgB,SACtB,IAAMC,EAAS,OAAQD,EAAU,UAAa,WACxCN,EAAKO,EAAUD,EAAU,GAAMA,EAAU,IAC/C,GAAI,CAACN,GAAMI,EAAS,IAAI,OAAOJ,CAAE,CAAC,EAAG,SACrC,IAAMQ,EAAOF,EAAU,IACvBD,EAAI,KAAK,CACP,GAAI,OAAOL,CAAE,EACb,WAAYQ,EAAOC,GAAWjB,EAAeiB,EAAGD,CAAG,EAAI,IAAM,KAG7D,GAAID,GAAU,CAAE,SAAU,CAACG,EAAUC,EAAaC,IAAgBN,EAAU,SAASI,EAAI,SAAUE,CAAK,CAAE,EAC1G,aAAc,GACd,cAAe,GACf,cAAe,GACf,mBAAoB,GACpB,KAAM,CAAE,WAAY,EAAK,CAC3B,CAAsB,CACxB,CACA,OAAOP,CACT","names":["getNestedValue","obj","path","acc","part","collectColumnIds","cols","c","id","buildFilterOnlyColumns","initialColumns","filters","existing","out","f","custom","key","r","row","_id","value"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
"use strict";var y=Object.defineProperty;var L=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var H=Object.prototype.hasOwnProperty;var V=(t,e)=>{for(var r in e)y(t,r,{get:e[r],enumerable:!0})},W=(t,e,r,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let l of j(e))!H.call(t,l)&&l!==r&&y(t,l,{get:()=>e[l],enumerable:!(i=L(e,l))||i.enumerable});return t};var _=t=>W(y({},"__esModule",{value:!0}),t);var q={};V(q,{DataTableAggregationFooter:()=>O});module.exports=_(q);var D=require("clsx"),v=require("tailwind-merge");function s(...t){return(0,v.twMerge)((0,D.clsx)(t))}var f=require("react/jsx-runtime");function A({className:t,...e}){return(0,f.jsx)("tfoot",{"data-slot":"table-footer",className:s("bg-muted/50 border-t font-medium [&>tr]:last:border-b-0",t),...e})}function z({className:t,...e}){return(0,f.jsx)("tr",{"data-slot":"table-row",className:s("hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors",t),...e})}function x({className:t,...e}){return(0,f.jsx)("td",{"data-slot":"table-cell",className:s("p-2 align-middle whitespace-nowrap",t),...e})}function C(t,e){if(!e)return{};let r=t.getIsPinned();if(!r)return{};let i=t.getSize();return{position:"sticky",left:r==="left"?t.getStart("left"):void 0,right:r==="right"?t.getAfter("right"):void 0,width:i,minWidth:i,maxWidth:i,boxShadow:r==="right"&&t.getIsFirstColumn("right")?"inset 1px 0 0 0 var(--border)":void 0}}var m=(t,e)=>e||t!==150?t:"auto";function M(t,e){return typeof e=="number"?t==="count"||t==="unique"?e.toLocaleString():e.toLocaleString(void 0,{minimumFractionDigits:2,maximumFractionDigits:2}):e}var o=require("react/jsx-runtime");function O({table:t,columnAggregations:e,aggregations:r,enableColumnPinning:i,enableRowSelection:l,showSerialNumbers:E,compact:T}){let w=Object.keys(e).length>0,P=t.getHeaderGroups()[0]?.headers.some(n=>n.column.columnDef.customFooter),p=E&&t.getFilteredRowModel().rows.length>0&&(w||P),S=t.getHeaderGroups()[0]?.headers.length??0,N=t.getVisibleLeafColumns().filter(n=>!n.getIsPinned()),G=N[N.length-1]?.id;return!w&&!P&&!p?null:(0,o.jsx)(A,{className:"bottom-0 z-20 sticky bg-sidebar border-t-0 shadow-[0_1px_0_0_var(--border)]",children:(0,o.jsx)(z,{className:"bg-sidebar hover:bg-transparent",children:t.getHeaderGroups()[0]?.headers.map((n,b)=>{let R=n.column.id,h=e[R],c=i&&(n.column.getIsPinned()==="left"||n.column.id==="serialNumber"||n.column.id==="select"&&l),g=i&&n.column.getIsPinned()==="right",d=n.column.id==="serialNumber",k=n.column.id==="select",a=n.column.columnDef.customFooter;return h||a||d&&p?(0,o.jsxs)(x,{className:s("relative px-2 py-2 font-semibold text-sm",b<S-1&&"border-r",T&&"py-1",c&&"sticky left-0 z-30 bg-sidebar",g&&"sticky right-0 z-30 bg-sidebar",(d||k)&&"sticky left-0 z-30 bg-sidebar",a?.className),style:{width:m(n.getSize(),c||g),minWidth:m(n.getSize(),c||g),...C(n.column,i)},children:[(0,o.jsx)("div",{className:"absolute top-0 inset-x-0 h-px bg-border pointer-events-none"}),(()=>{if(a?.content){let u=typeof a.content=="function"?a.content(t):a.content;return(0,o.jsx)("div",{className:s("w-full h-full",a.align==="center"&&"text-center",a.align==="right"&&"text-right",a.align==="left"&&"text-left"),children:u})}return h?(0,o.jsx)("div",{className:"flex flex-col gap-0.5 text-xs",children:Object.entries(h).map(([u,F])=>(0,o.jsxs)("div",{className:"flex justify-between items-center text-muted-foreground",children:[(0,o.jsx)("span",{className:"text-xs capitalize",children:u}),(0,o.jsx)("span",{className:"font-medium text-foreground",children:r?.[R]?.format?.(F,u)??M(u,F)})]},u))}):d&&p?(0,o.jsxs)("div",{className:"text-muted-foreground text-xs text-center",children:["Total ",t.getFilteredRowModel().rows.length]}):null})()]},`agg-${n.id}`):(0,o.jsx)(x,{className:s("relative px-0 py-0",b<S-1&&n.column.id!==G&&"border-r",T&&"py-0",c&&"sticky left-0 z-30 bg-sidebar",g&&"sticky right-0 z-30 bg-sidebar",(d||k)&&"sticky left-0 z-30 bg-sidebar"),style:{width:m(n.getSize(),c||g),minWidth:m(n.getSize(),c||g),...C(n.column,i)},children:(0,o.jsx)("div",{className:"absolute top-0 inset-x-0 h-px bg-border pointer-events-none"})},`agg-${n.id}`)})})})}0&&(module.exports={DataTableAggregationFooter});
|
|
3
|
+
//# sourceMappingURL=data-table-footer.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/data/data-table/data-table-footer.tsx","../../../../src/lib/utils.ts","../../../../src/components/ui/table.tsx","../../../../src/components/data/data-table/data-table-pinning.ts","../../../../src/components/data/data-table/data-table-aggregation.ts"],"sourcesContent":["import type { Table } from \"@tanstack/react-table\"\nimport { TableCell, TableFooter, TableRow } from \"../../ui/table.jsx\"\nimport { cn } from \"../../../lib/utils.js\"\nimport type { AggregationConfigMap, AggregationFunction, GroupColumnDef } from \"./data-table-types.js\"\nimport { getPinningStyles, stickyWidth } from \"./data-table-pinning.js\"\nimport { formatAggregationValue } from \"./data-table-aggregation.js\"\n\ninterface DataTableAggregationFooterProps<T> {\n table: Table<T>\n columnAggregations: Record<string, Record<string, any>>\n aggregations: AggregationConfigMap<T>\n enableColumnPinning: boolean\n enableRowSelection: boolean\n showSerialNumbers: boolean\n bordered: boolean\n compact: boolean\n}\n\n/** Sticky aggregation/custom footer row. Renders null when there's nothing to show. */\nexport function DataTableAggregationFooter<T>({\n table,\n columnAggregations,\n aggregations,\n enableColumnPinning,\n enableRowSelection,\n showSerialNumbers,\n compact,\n}: DataTableAggregationFooterProps<T>) {\n const hasColumnAggregations = Object.keys(columnAggregations).length > 0\n\n const hasCustomFooters = table.getHeaderGroups()[0]?.headers.some((header) => {\n const columnDef = header.column.columnDef as GroupColumnDef<T>\n return columnDef.customFooter\n })\n\n // Show serial number total ONLY when we have aggregations\n const shouldShowSerialTotal =\n showSerialNumbers &&\n table.getFilteredRowModel().rows.length > 0 &&\n (hasColumnAggregations || hasCustomFooters)\n\n const footerColCount = table.getHeaderGroups()[0]?.headers.length ?? 0\n const centerCols = table.getVisibleLeafColumns().filter((c) => !c.getIsPinned())\n const lastCenterId = centerCols[centerCols.length - 1]?.id\n\n if (!hasColumnAggregations && !hasCustomFooters && !shouldShowSerialTotal) {\n return null\n }\n\n // box-shadow doubles as the footer's bottom border AND covers the sub-pixel seam\n // fractional zoom leaves under a sticky tfoot (a real border-b gets suppressed by\n // the ui Table's [&>tr]:last:border-b-0 and needs !important to win)\n return (\n <TableFooter className=\"bottom-0 z-20 sticky bg-sidebar border-t-0 shadow-[0_1px_0_0_var(--border)]\">\n <TableRow className=\"bg-sidebar hover:bg-transparent\">\n {table.getHeaderGroups()[0]?.headers.map((header, index) => {\n const columnId = header.column.id\n const columnAgg = columnAggregations[columnId]\n const isPinnedLeft =\n enableColumnPinning &&\n (header.column.getIsPinned() === \"left\" ||\n header.column.id === \"serialNumber\" ||\n (header.column.id === \"select\" && enableRowSelection))\n const isPinnedRight = enableColumnPinning && header.column.getIsPinned() === \"right\"\n const isSerialNumber = header.column.id === \"serialNumber\"\n const isCheckbox = header.column.id === \"select\"\n\n const columnDef = header.column.columnDef as GroupColumnDef<T>\n const columnFooter = columnDef.customFooter\n\n const hasContent =\n columnAgg || columnFooter || (isSerialNumber && shouldShowSerialTotal)\n\n if (!hasContent) {\n return (\n <TableCell\n key={`agg-${header.id}`}\n className={cn(\n \"relative px-0 py-0\",\n index < footerColCount - 1 && header.column.id !== lastCenterId && \"border-r\",\n compact && \"py-0\",\n isPinnedLeft && \"sticky left-0 z-30 bg-sidebar\",\n isPinnedRight && \"sticky right-0 z-30 bg-sidebar\",\n (isSerialNumber || isCheckbox) && \"sticky left-0 z-30 bg-sidebar\"\n )}\n style={{\n width: stickyWidth(header.getSize(), isPinnedLeft || isPinnedRight),\n minWidth: stickyWidth(header.getSize(), isPinnedLeft || isPinnedRight),\n ...getPinningStyles(header.column, enableColumnPinning),\n }}\n >\n <div className=\"absolute top-0 inset-x-0 h-px bg-border pointer-events-none\" />\n </TableCell>\n )\n }\n\n return (\n <TableCell\n key={`agg-${header.id}`}\n className={cn(\n \"relative px-2 py-2 font-semibold text-sm\",\n index < footerColCount - 1 && \"border-r\",\n compact && \"py-1\",\n isPinnedLeft && \"sticky left-0 z-30 bg-sidebar\",\n isPinnedRight && \"sticky right-0 z-30 bg-sidebar\",\n (isSerialNumber || isCheckbox) && \"sticky left-0 z-30 bg-sidebar\",\n columnFooter?.className\n )}\n style={{\n width: stickyWidth(header.getSize(), isPinnedLeft || isPinnedRight),\n minWidth: stickyWidth(header.getSize(), isPinnedLeft || isPinnedRight),\n ...getPinningStyles(header.column, enableColumnPinning),\n }}\n >\n {/* Sticky-safe top border (CSS border on sticky footer scrolls away) */}\n <div className=\"absolute top-0 inset-x-0 h-px bg-border pointer-events-none\" />\n {(() => {\n if (columnFooter?.content) {\n const content =\n typeof columnFooter.content === \"function\"\n ? columnFooter.content(table)\n : columnFooter.content\n return (\n <div\n className={cn(\n \"w-full h-full\",\n columnFooter.align === \"center\" && \"text-center\",\n columnFooter.align === \"right\" && \"text-right\",\n columnFooter.align === \"left\" && \"text-left\"\n )}\n >\n {content}\n </div>\n )\n }\n\n if (columnAgg) {\n return (\n <div className=\"flex flex-col gap-0.5 text-xs\">\n {Object.entries(columnAgg).map(([func, value]) => (\n <div\n key={func}\n className=\"flex justify-between items-center text-muted-foreground\"\n >\n <span className=\"text-xs capitalize\">{func}</span>\n <span className=\"font-medium text-foreground\">\n {aggregations?.[columnId]?.format?.(value, func as AggregationFunction) ??\n formatAggregationValue(func, value)}\n </span>\n </div>\n ))}\n </div>\n )\n }\n\n if (isSerialNumber && shouldShowSerialTotal) {\n return (\n <div className=\"text-muted-foreground text-xs text-center\">\n Total {table.getFilteredRowModel().rows.length}\n </div>\n )\n }\n\n return null\n })()}\n </TableCell>\n )\n })}\n </TableRow>\n </TableFooter>\n )\n}\n","import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}","import * as React from \"react\"\n\nimport { cn } from \"../../lib/utils.js\"\n\nfunction Table({ className, ...props }: React.ComponentProps<\"table\">) {\n return (\n <div\n data-slot=\"table-container\"\n className=\"relative w-full h-full max-h-full overflow-auto\"\n >\n <table\n data-slot=\"table\"\n className={cn(\"w-full caption-bottom text-sm\", className)}\n {...props}\n />\n </div>\n )\n}\n\nfunction TableHeader({ className, ...props }: React.ComponentProps<\"thead\">) {\n return (\n <thead\n data-slot=\"table-header\"\n className={cn(\"[&_tr]:border-b\", className)}\n {...props}\n />\n )\n}\n\nfunction TableBody({ className, ...props }: React.ComponentProps<\"tbody\">) {\n return (\n <tbody\n data-slot=\"table-body\"\n className={cn(\"[&_tr:last-child]:border-0\", className)}\n {...props}\n />\n )\n}\n\nfunction TableFooter({ className, ...props }: React.ComponentProps<\"tfoot\">) {\n return (\n <tfoot\n data-slot=\"table-footer\"\n className={cn(\n \"bg-muted/50 border-t font-medium [&>tr]:last:border-b-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableRow({ className, ...props }: React.ComponentProps<\"tr\">) {\n return (\n <tr\n data-slot=\"table-row\"\n className={cn(\n \"hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableHead({ className, ...props }: React.ComponentProps<\"th\">) {\n return (\n <th\n data-slot=\"table-head\"\n className={cn(\n \"text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableCell({ className, ...props }: React.ComponentProps<\"td\">) {\n return (\n <td\n data-slot=\"table-cell\"\n className={cn(\n \"p-2 align-middle whitespace-nowrap\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableCaption({\n className,\n ...props\n}: React.ComponentProps<\"caption\">) {\n return (\n <caption\n data-slot=\"table-caption\"\n className={cn(\"text-muted-foreground mt-4 text-sm\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n}\n","import type { Column, ColumnPinningState, Table } from \"@tanstack/react-table\"\nimport type { CSSProperties } from \"react\"\nimport type { GroupColumnDef } from \"./data-table-types.js\"\n\n/**\n * Sticky styles for a pinned column cell — TanStack's official pinning pattern\n * (`getStart`/`getAfter` offsets; column locked to `size` so offsets stay true; 1px inset\n * shadow separates the first right-pinned column).\n */\nexport function getPinningStyles(\n column: Column<any, unknown>,\n enableColumnPinning: boolean,\n): CSSProperties {\n if (!enableColumnPinning) return {}\n const pinned = column.getIsPinned()\n if (!pinned) return {}\n\n const size = column.getSize()\n\n return {\n position: \"sticky\",\n left: pinned === \"left\" ? column.getStart(\"left\") : undefined,\n right: pinned === \"right\" ? column.getAfter(\"right\") : undefined,\n width: size,\n minWidth: size,\n maxWidth: size,\n // box-shadow (not border) stays put on sticky cells; marks the right-pinned group's left edge\n boxShadow:\n pinned === \"right\" && column.getIsFirstColumn(\"right\")\n ? \"inset 1px 0 0 0 var(--border)\"\n : undefined,\n }\n}\n\n/** Width for a non-pinned cell: explicit size or auto (150 = TanStack default = auto). */\nexport const stickyWidth = (size: number, isPinned: boolean): number | string =>\n isPinned ? size : size !== 150 ? size : \"auto\"\n\n/**\n * Resolve `defaultPin`/`pinIndex` off the raw column defs (recursing into group columns) into\n * ordered left/right id lists for the table's initial pinning state. Lower `pinIndex` sits\n * closer to the outer edge; columns without a finite `pinIndex` keep declaration order.\n * Defensive against bad input (duplicate/malformed ids, non-numeric `pinIndex`, an invalid\n * `defaultPin` value slipping through from untyped JS callers): each is skipped or falls back\n * rather than corrupting the pinning state.\n */\nexport function collectDefaultPinned<T>(columns: GroupColumnDef<T>[]): { left: string[]; right: string[] } {\n type Entry = { id: string; order: number }\n const left: Entry[] = []\n const right: Entry[] = []\n const seen = new Set<string>()\n\n const walk = (cols: GroupColumnDef<T>[]) => {\n cols.forEach((col, index) => {\n const rawId = (col as any).id ?? (col as any).accessorKey\n const id = rawId != null ? String(rawId) : \"\"\n if (id && (col.defaultPin === \"left\" || col.defaultPin === \"right\") && !seen.has(id)) {\n seen.add(id)\n const order = Number.isFinite(col.pinIndex as number) ? (col.pinIndex as number) : index\n ;(col.defaultPin === \"left\" ? left : right).push({ id, order })\n }\n if (col.columns) walk(col.columns)\n })\n }\n walk(columns)\n\n // stable sort (spec-guaranteed since ES2019): equal/duplicate `order` values keep declaration order\n const toIds = (entries: Entry[]) => entries.sort((a, b) => a.order - b.order).map((e) => e.id)\n return { left: toIds(left), right: toIds(right) }\n}\n\n/** Re-assert the always-left-pinned helper columns on every pinning change. */\nexport function enforceAlwaysPinned(next: ColumnPinningState, always: string[]): ColumnPinningState {\n return {\n left: [...always, ...(next.left ?? []).filter((id) => !always.includes(id))],\n right: (next.right ?? []).filter((id) => !always.includes(id)),\n }\n}\n\n/**\n * Pin/unpin a column. Captures the column's live rendered width on pin (so it doesn't jump to\n * its declared `size`) and drops the override on unpin.\n */\nexport function pinColumn<T>(\n table: Table<T>,\n columnId: string,\n side: \"left\" | \"right\" | false,\n opts: { container: HTMLElement | null; alwaysPinnedLeft: string[] },\n) {\n if (side === false) {\n table.setColumnSizing((prev) => {\n const next = { ...prev }\n delete next[columnId]\n return next\n })\n } else {\n const headerEl = opts.container?.querySelector<HTMLElement>(`[data-col-id=\"${columnId}\"]`)\n const width = headerEl ? Math.round(headerEl.getBoundingClientRect().width) : 0\n if (width > 0) table.setColumnSizing((prev) => ({ ...prev, [columnId]: width }))\n }\n\n const { alwaysPinnedLeft } = opts\n const current = table.getState().columnPinning\n const newPinning = {\n left: (current.left ?? []).filter((id) => alwaysPinnedLeft.includes(id)),\n right: [...(current.right ?? [])],\n }\n\n if (side === \"right\") {\n if (!newPinning.right.includes(columnId)) newPinning.right.push(columnId)\n } else if (side === \"left\") {\n newPinning.right = newPinning.right.filter((id) => id !== columnId)\n if (!newPinning.left.includes(columnId) && !alwaysPinnedLeft.includes(columnId)) {\n newPinning.left.push(columnId)\n }\n } else {\n newPinning.left = newPinning.left.filter((id) => id !== columnId)\n newPinning.right = newPinning.right.filter((id) => id !== columnId)\n }\n\n table.setColumnPinning(newPinning)\n}\n","import type { Table } from \"@tanstack/react-table\"\nimport type { AggregationConfigMap } from \"./data-table-types.js\"\n\n/** Aggregation reducers, keyed by function name. */\nexport const aggregationFunctions = {\n sum: (values: number[]) => values.reduce((acc, val) => acc + val, 0),\n average: (values: number[]) =>\n values.length > 0 ? values.reduce((acc, val) => acc + val, 0) / values.length : 0,\n min: (values: number[]) => (values.length > 0 ? Math.min(...values) : 0),\n max: (values: number[]) => (values.length > 0 ? Math.max(...values) : 0),\n count: (values: any[]) => values.length,\n unique: (values: any[]) => new Set(values).size,\n median: (values: number[]) => {\n if (values.length === 0) return 0\n const sorted = [...values].sort((a, b) => a - b)\n const mid = Math.floor(sorted.length / 2)\n return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid]\n },\n} as const\n\n/**\n * Compute the configured aggregations over the table's filtered rows.\n * Returns `{ [columnId]: { [func]: value } }`.\n */\nexport function computeColumnAggregations<T>(\n table: Table<T>,\n aggregations: AggregationConfigMap<T>,\n): Record<string, Record<string, any>> {\n if (!aggregations || Object.keys(aggregations).length === 0) return {}\n\n const result: Record<string, Record<string, any>> = {}\n const allFilteredRows = table.getFilteredRowModel().rows\n\n Object.entries(aggregations).forEach(([columnId, config]) => {\n if (!config?.enabled) return\n\n const values = allFilteredRows\n .map((row) => {\n if (config.accessor) {\n return config.accessor(row.original)\n }\n const value = row.getValue(columnId)\n // Non-numeric cells -> NaN (dropped below), NOT 0 — coercing to 0 skewed avg/min/max.\n return typeof value === \"number\" ? value : parseFloat(String(value))\n })\n .filter((val): val is number => val !== null && !isNaN(val))\n\n const aggResults: Record<string, any> = {}\n config.functions?.forEach((func) => {\n if (aggregationFunctions[func]) {\n aggResults[func] = aggregationFunctions[func](values)\n }\n })\n\n if (Object.keys(aggResults).length > 0) {\n result[columnId] = aggResults\n }\n })\n\n return result\n}\n\n/** Format an aggregation value for display (counts as integers, others to 2 decimals). */\nexport function formatAggregationValue(func: string, value: any) {\n if (typeof value === \"number\") {\n if (func === \"count\" || func === \"unique\") {\n return value.toLocaleString()\n }\n return value.toLocaleString(undefined, {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n })\n }\n return value\n}\n"],"mappings":"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","names":["data_table_footer_exports","__export","DataTableAggregationFooter","__toCommonJS","import_clsx","import_tailwind_merge","cn","inputs","import_jsx_runtime","TableFooter","className","props","cn","TableRow","TableCell","className","props","cn","getPinningStyles","column","enableColumnPinning","pinned","size","stickyWidth","isPinned","formatAggregationValue","func","value","import_jsx_runtime","DataTableAggregationFooter","table","columnAggregations","aggregations","enableColumnPinning","enableRowSelection","showSerialNumbers","compact","hasColumnAggregations","hasCustomFooters","header","shouldShowSerialTotal","footerColCount","centerCols","c","lastCenterId","TableFooter","TableRow","index","columnId","columnAgg","isPinnedLeft","isPinnedRight","isSerialNumber","isCheckbox","columnFooter","TableCell","cn","stickyWidth","getPinningStyles","content","func","value","formatAggregationValue"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { Table } from '@tanstack/react-table';
|
|
3
|
+
import { AggregationConfigMap } from './data-table-types.cjs';
|
|
4
|
+
import 'lucide-react';
|
|
5
|
+
import './data-table-persist.cjs';
|
|
6
|
+
import './data-table-export.cjs';
|
|
7
|
+
|
|
8
|
+
interface DataTableAggregationFooterProps<T> {
|
|
9
|
+
table: Table<T>;
|
|
10
|
+
columnAggregations: Record<string, Record<string, any>>;
|
|
11
|
+
aggregations: AggregationConfigMap<T>;
|
|
12
|
+
enableColumnPinning: boolean;
|
|
13
|
+
enableRowSelection: boolean;
|
|
14
|
+
showSerialNumbers: boolean;
|
|
15
|
+
bordered: boolean;
|
|
16
|
+
compact: boolean;
|
|
17
|
+
}
|
|
18
|
+
/** Sticky aggregation/custom footer row. Renders null when there's nothing to show. */
|
|
19
|
+
declare function DataTableAggregationFooter<T>({ table, columnAggregations, aggregations, enableColumnPinning, enableRowSelection, showSerialNumbers, compact, }: DataTableAggregationFooterProps<T>): react_jsx_runtime.JSX.Element | null;
|
|
20
|
+
|
|
21
|
+
export { DataTableAggregationFooter };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { Table } from '@tanstack/react-table';
|
|
3
|
+
import { AggregationConfigMap } from './data-table-types.js';
|
|
4
|
+
import 'lucide-react';
|
|
5
|
+
import './data-table-persist.js';
|
|
6
|
+
import './data-table-export.js';
|
|
7
|
+
|
|
8
|
+
interface DataTableAggregationFooterProps<T> {
|
|
9
|
+
table: Table<T>;
|
|
10
|
+
columnAggregations: Record<string, Record<string, any>>;
|
|
11
|
+
aggregations: AggregationConfigMap<T>;
|
|
12
|
+
enableColumnPinning: boolean;
|
|
13
|
+
enableRowSelection: boolean;
|
|
14
|
+
showSerialNumbers: boolean;
|
|
15
|
+
bordered: boolean;
|
|
16
|
+
compact: boolean;
|
|
17
|
+
}
|
|
18
|
+
/** Sticky aggregation/custom footer row. Renders null when there's nothing to show. */
|
|
19
|
+
declare function DataTableAggregationFooter<T>({ table, columnAggregations, aggregations, enableColumnPinning, enableRowSelection, showSerialNumbers, compact, }: DataTableAggregationFooterProps<T>): react_jsx_runtime.JSX.Element | null;
|
|
20
|
+
|
|
21
|
+
export { DataTableAggregationFooter };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
import{clsx as E}from"clsx";import{twMerge as G}from"tailwind-merge";function a(...t){return G(E(t))}import{jsx as h}from"react/jsx-runtime";function F({className:t,...n}){return h("tfoot",{"data-slot":"table-footer",className:a("bg-muted/50 border-t font-medium [&>tr]:last:border-b-0",t),...n})}function D({className:t,...n}){return h("tr",{"data-slot":"table-row",className:a("hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors",t),...n})}function b({className:t,...n}){return h("td",{"data-slot":"table-cell",className:a("p-2 align-middle whitespace-nowrap",t),...n})}function y(t,n){if(!n)return{};let s=t.getIsPinned();if(!s)return{};let i=t.getSize();return{position:"sticky",left:s==="left"?t.getStart("left"):void 0,right:s==="right"?t.getAfter("right"):void 0,width:i,minWidth:i,maxWidth:i,boxShadow:s==="right"&&t.getIsFirstColumn("right")?"inset 1px 0 0 0 var(--border)":void 0}}var u=(t,n)=>n||t!==150?t:"auto";function v(t,n){return typeof n=="number"?t==="count"||t==="unique"?n.toLocaleString():n.toLocaleString(void 0,{minimumFractionDigits:2,maximumFractionDigits:2}):n}import{jsx as r,jsxs as x}from"react/jsx-runtime";function U({table:t,columnAggregations:n,aggregations:s,enableColumnPinning:i,enableRowSelection:A,showSerialNumbers:z,compact:C}){let T=Object.keys(n).length>0,w=t.getHeaderGroups()[0]?.headers.some(e=>e.column.columnDef.customFooter),d=z&&t.getFilteredRowModel().rows.length>0&&(T||w),P=t.getHeaderGroups()[0]?.headers.length??0,S=t.getVisibleLeafColumns().filter(e=>!e.getIsPinned()),M=S[S.length-1]?.id;return!T&&!w&&!d?null:r(F,{className:"bottom-0 z-20 sticky bg-sidebar border-t-0 shadow-[0_1px_0_0_var(--border)]",children:r(D,{className:"bg-sidebar hover:bg-transparent",children:t.getHeaderGroups()[0]?.headers.map((e,f)=>{let N=e.column.id,p=n[N],l=i&&(e.column.getIsPinned()==="left"||e.column.id==="serialNumber"||e.column.id==="select"&&A),c=i&&e.column.getIsPinned()==="right",m=e.column.id==="serialNumber",R=e.column.id==="select",o=e.column.columnDef.customFooter;return p||o||m&&d?x(b,{className:a("relative px-2 py-2 font-semibold text-sm",f<P-1&&"border-r",C&&"py-1",l&&"sticky left-0 z-30 bg-sidebar",c&&"sticky right-0 z-30 bg-sidebar",(m||R)&&"sticky left-0 z-30 bg-sidebar",o?.className),style:{width:u(e.getSize(),l||c),minWidth:u(e.getSize(),l||c),...y(e.column,i)},children:[r("div",{className:"absolute top-0 inset-x-0 h-px bg-border pointer-events-none"}),(()=>{if(o?.content){let g=typeof o.content=="function"?o.content(t):o.content;return r("div",{className:a("w-full h-full",o.align==="center"&&"text-center",o.align==="right"&&"text-right",o.align==="left"&&"text-left"),children:g})}return p?r("div",{className:"flex flex-col gap-0.5 text-xs",children:Object.entries(p).map(([g,k])=>x("div",{className:"flex justify-between items-center text-muted-foreground",children:[r("span",{className:"text-xs capitalize",children:g}),r("span",{className:"font-medium text-foreground",children:s?.[N]?.format?.(k,g)??v(g,k)})]},g))}):m&&d?x("div",{className:"text-muted-foreground text-xs text-center",children:["Total ",t.getFilteredRowModel().rows.length]}):null})()]},`agg-${e.id}`):r(b,{className:a("relative px-0 py-0",f<P-1&&e.column.id!==M&&"border-r",C&&"py-0",l&&"sticky left-0 z-30 bg-sidebar",c&&"sticky right-0 z-30 bg-sidebar",(m||R)&&"sticky left-0 z-30 bg-sidebar"),style:{width:u(e.getSize(),l||c),minWidth:u(e.getSize(),l||c),...y(e.column,i)},children:r("div",{className:"absolute top-0 inset-x-0 h-px bg-border pointer-events-none"})},`agg-${e.id}`)})})})}export{U as DataTableAggregationFooter};
|
|
3
|
+
//# sourceMappingURL=data-table-footer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/utils.ts","../../../../src/components/ui/table.tsx","../../../../src/components/data/data-table/data-table-pinning.ts","../../../../src/components/data/data-table/data-table-aggregation.ts","../../../../src/components/data/data-table/data-table-footer.tsx"],"sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}","import * as React from \"react\"\n\nimport { cn } from \"../../lib/utils.js\"\n\nfunction Table({ className, ...props }: React.ComponentProps<\"table\">) {\n return (\n <div\n data-slot=\"table-container\"\n className=\"relative w-full h-full max-h-full overflow-auto\"\n >\n <table\n data-slot=\"table\"\n className={cn(\"w-full caption-bottom text-sm\", className)}\n {...props}\n />\n </div>\n )\n}\n\nfunction TableHeader({ className, ...props }: React.ComponentProps<\"thead\">) {\n return (\n <thead\n data-slot=\"table-header\"\n className={cn(\"[&_tr]:border-b\", className)}\n {...props}\n />\n )\n}\n\nfunction TableBody({ className, ...props }: React.ComponentProps<\"tbody\">) {\n return (\n <tbody\n data-slot=\"table-body\"\n className={cn(\"[&_tr:last-child]:border-0\", className)}\n {...props}\n />\n )\n}\n\nfunction TableFooter({ className, ...props }: React.ComponentProps<\"tfoot\">) {\n return (\n <tfoot\n data-slot=\"table-footer\"\n className={cn(\n \"bg-muted/50 border-t font-medium [&>tr]:last:border-b-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableRow({ className, ...props }: React.ComponentProps<\"tr\">) {\n return (\n <tr\n data-slot=\"table-row\"\n className={cn(\n \"hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableHead({ className, ...props }: React.ComponentProps<\"th\">) {\n return (\n <th\n data-slot=\"table-head\"\n className={cn(\n \"text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableCell({ className, ...props }: React.ComponentProps<\"td\">) {\n return (\n <td\n data-slot=\"table-cell\"\n className={cn(\n \"p-2 align-middle whitespace-nowrap\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableCaption({\n className,\n ...props\n}: React.ComponentProps<\"caption\">) {\n return (\n <caption\n data-slot=\"table-caption\"\n className={cn(\"text-muted-foreground mt-4 text-sm\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n}\n","import type { Column, ColumnPinningState, Table } from \"@tanstack/react-table\"\nimport type { CSSProperties } from \"react\"\nimport type { GroupColumnDef } from \"./data-table-types.js\"\n\n/**\n * Sticky styles for a pinned column cell — TanStack's official pinning pattern\n * (`getStart`/`getAfter` offsets; column locked to `size` so offsets stay true; 1px inset\n * shadow separates the first right-pinned column).\n */\nexport function getPinningStyles(\n column: Column<any, unknown>,\n enableColumnPinning: boolean,\n): CSSProperties {\n if (!enableColumnPinning) return {}\n const pinned = column.getIsPinned()\n if (!pinned) return {}\n\n const size = column.getSize()\n\n return {\n position: \"sticky\",\n left: pinned === \"left\" ? column.getStart(\"left\") : undefined,\n right: pinned === \"right\" ? column.getAfter(\"right\") : undefined,\n width: size,\n minWidth: size,\n maxWidth: size,\n // box-shadow (not border) stays put on sticky cells; marks the right-pinned group's left edge\n boxShadow:\n pinned === \"right\" && column.getIsFirstColumn(\"right\")\n ? \"inset 1px 0 0 0 var(--border)\"\n : undefined,\n }\n}\n\n/** Width for a non-pinned cell: explicit size or auto (150 = TanStack default = auto). */\nexport const stickyWidth = (size: number, isPinned: boolean): number | string =>\n isPinned ? size : size !== 150 ? size : \"auto\"\n\n/**\n * Resolve `defaultPin`/`pinIndex` off the raw column defs (recursing into group columns) into\n * ordered left/right id lists for the table's initial pinning state. Lower `pinIndex` sits\n * closer to the outer edge; columns without a finite `pinIndex` keep declaration order.\n * Defensive against bad input (duplicate/malformed ids, non-numeric `pinIndex`, an invalid\n * `defaultPin` value slipping through from untyped JS callers): each is skipped or falls back\n * rather than corrupting the pinning state.\n */\nexport function collectDefaultPinned<T>(columns: GroupColumnDef<T>[]): { left: string[]; right: string[] } {\n type Entry = { id: string; order: number }\n const left: Entry[] = []\n const right: Entry[] = []\n const seen = new Set<string>()\n\n const walk = (cols: GroupColumnDef<T>[]) => {\n cols.forEach((col, index) => {\n const rawId = (col as any).id ?? (col as any).accessorKey\n const id = rawId != null ? String(rawId) : \"\"\n if (id && (col.defaultPin === \"left\" || col.defaultPin === \"right\") && !seen.has(id)) {\n seen.add(id)\n const order = Number.isFinite(col.pinIndex as number) ? (col.pinIndex as number) : index\n ;(col.defaultPin === \"left\" ? left : right).push({ id, order })\n }\n if (col.columns) walk(col.columns)\n })\n }\n walk(columns)\n\n // stable sort (spec-guaranteed since ES2019): equal/duplicate `order` values keep declaration order\n const toIds = (entries: Entry[]) => entries.sort((a, b) => a.order - b.order).map((e) => e.id)\n return { left: toIds(left), right: toIds(right) }\n}\n\n/** Re-assert the always-left-pinned helper columns on every pinning change. */\nexport function enforceAlwaysPinned(next: ColumnPinningState, always: string[]): ColumnPinningState {\n return {\n left: [...always, ...(next.left ?? []).filter((id) => !always.includes(id))],\n right: (next.right ?? []).filter((id) => !always.includes(id)),\n }\n}\n\n/**\n * Pin/unpin a column. Captures the column's live rendered width on pin (so it doesn't jump to\n * its declared `size`) and drops the override on unpin.\n */\nexport function pinColumn<T>(\n table: Table<T>,\n columnId: string,\n side: \"left\" | \"right\" | false,\n opts: { container: HTMLElement | null; alwaysPinnedLeft: string[] },\n) {\n if (side === false) {\n table.setColumnSizing((prev) => {\n const next = { ...prev }\n delete next[columnId]\n return next\n })\n } else {\n const headerEl = opts.container?.querySelector<HTMLElement>(`[data-col-id=\"${columnId}\"]`)\n const width = headerEl ? Math.round(headerEl.getBoundingClientRect().width) : 0\n if (width > 0) table.setColumnSizing((prev) => ({ ...prev, [columnId]: width }))\n }\n\n const { alwaysPinnedLeft } = opts\n const current = table.getState().columnPinning\n const newPinning = {\n left: (current.left ?? []).filter((id) => alwaysPinnedLeft.includes(id)),\n right: [...(current.right ?? [])],\n }\n\n if (side === \"right\") {\n if (!newPinning.right.includes(columnId)) newPinning.right.push(columnId)\n } else if (side === \"left\") {\n newPinning.right = newPinning.right.filter((id) => id !== columnId)\n if (!newPinning.left.includes(columnId) && !alwaysPinnedLeft.includes(columnId)) {\n newPinning.left.push(columnId)\n }\n } else {\n newPinning.left = newPinning.left.filter((id) => id !== columnId)\n newPinning.right = newPinning.right.filter((id) => id !== columnId)\n }\n\n table.setColumnPinning(newPinning)\n}\n","import type { Table } from \"@tanstack/react-table\"\nimport type { AggregationConfigMap } from \"./data-table-types.js\"\n\n/** Aggregation reducers, keyed by function name. */\nexport const aggregationFunctions = {\n sum: (values: number[]) => values.reduce((acc, val) => acc + val, 0),\n average: (values: number[]) =>\n values.length > 0 ? values.reduce((acc, val) => acc + val, 0) / values.length : 0,\n min: (values: number[]) => (values.length > 0 ? Math.min(...values) : 0),\n max: (values: number[]) => (values.length > 0 ? Math.max(...values) : 0),\n count: (values: any[]) => values.length,\n unique: (values: any[]) => new Set(values).size,\n median: (values: number[]) => {\n if (values.length === 0) return 0\n const sorted = [...values].sort((a, b) => a - b)\n const mid = Math.floor(sorted.length / 2)\n return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid]\n },\n} as const\n\n/**\n * Compute the configured aggregations over the table's filtered rows.\n * Returns `{ [columnId]: { [func]: value } }`.\n */\nexport function computeColumnAggregations<T>(\n table: Table<T>,\n aggregations: AggregationConfigMap<T>,\n): Record<string, Record<string, any>> {\n if (!aggregations || Object.keys(aggregations).length === 0) return {}\n\n const result: Record<string, Record<string, any>> = {}\n const allFilteredRows = table.getFilteredRowModel().rows\n\n Object.entries(aggregations).forEach(([columnId, config]) => {\n if (!config?.enabled) return\n\n const values = allFilteredRows\n .map((row) => {\n if (config.accessor) {\n return config.accessor(row.original)\n }\n const value = row.getValue(columnId)\n // Non-numeric cells -> NaN (dropped below), NOT 0 — coercing to 0 skewed avg/min/max.\n return typeof value === \"number\" ? value : parseFloat(String(value))\n })\n .filter((val): val is number => val !== null && !isNaN(val))\n\n const aggResults: Record<string, any> = {}\n config.functions?.forEach((func) => {\n if (aggregationFunctions[func]) {\n aggResults[func] = aggregationFunctions[func](values)\n }\n })\n\n if (Object.keys(aggResults).length > 0) {\n result[columnId] = aggResults\n }\n })\n\n return result\n}\n\n/** Format an aggregation value for display (counts as integers, others to 2 decimals). */\nexport function formatAggregationValue(func: string, value: any) {\n if (typeof value === \"number\") {\n if (func === \"count\" || func === \"unique\") {\n return value.toLocaleString()\n }\n return value.toLocaleString(undefined, {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n })\n }\n return value\n}\n","import type { Table } from \"@tanstack/react-table\"\nimport { TableCell, TableFooter, TableRow } from \"../../ui/table.jsx\"\nimport { cn } from \"../../../lib/utils.js\"\nimport type { AggregationConfigMap, AggregationFunction, GroupColumnDef } from \"./data-table-types.js\"\nimport { getPinningStyles, stickyWidth } from \"./data-table-pinning.js\"\nimport { formatAggregationValue } from \"./data-table-aggregation.js\"\n\ninterface DataTableAggregationFooterProps<T> {\n table: Table<T>\n columnAggregations: Record<string, Record<string, any>>\n aggregations: AggregationConfigMap<T>\n enableColumnPinning: boolean\n enableRowSelection: boolean\n showSerialNumbers: boolean\n bordered: boolean\n compact: boolean\n}\n\n/** Sticky aggregation/custom footer row. Renders null when there's nothing to show. */\nexport function DataTableAggregationFooter<T>({\n table,\n columnAggregations,\n aggregations,\n enableColumnPinning,\n enableRowSelection,\n showSerialNumbers,\n compact,\n}: DataTableAggregationFooterProps<T>) {\n const hasColumnAggregations = Object.keys(columnAggregations).length > 0\n\n const hasCustomFooters = table.getHeaderGroups()[0]?.headers.some((header) => {\n const columnDef = header.column.columnDef as GroupColumnDef<T>\n return columnDef.customFooter\n })\n\n // Show serial number total ONLY when we have aggregations\n const shouldShowSerialTotal =\n showSerialNumbers &&\n table.getFilteredRowModel().rows.length > 0 &&\n (hasColumnAggregations || hasCustomFooters)\n\n const footerColCount = table.getHeaderGroups()[0]?.headers.length ?? 0\n const centerCols = table.getVisibleLeafColumns().filter((c) => !c.getIsPinned())\n const lastCenterId = centerCols[centerCols.length - 1]?.id\n\n if (!hasColumnAggregations && !hasCustomFooters && !shouldShowSerialTotal) {\n return null\n }\n\n // box-shadow doubles as the footer's bottom border AND covers the sub-pixel seam\n // fractional zoom leaves under a sticky tfoot (a real border-b gets suppressed by\n // the ui Table's [&>tr]:last:border-b-0 and needs !important to win)\n return (\n <TableFooter className=\"bottom-0 z-20 sticky bg-sidebar border-t-0 shadow-[0_1px_0_0_var(--border)]\">\n <TableRow className=\"bg-sidebar hover:bg-transparent\">\n {table.getHeaderGroups()[0]?.headers.map((header, index) => {\n const columnId = header.column.id\n const columnAgg = columnAggregations[columnId]\n const isPinnedLeft =\n enableColumnPinning &&\n (header.column.getIsPinned() === \"left\" ||\n header.column.id === \"serialNumber\" ||\n (header.column.id === \"select\" && enableRowSelection))\n const isPinnedRight = enableColumnPinning && header.column.getIsPinned() === \"right\"\n const isSerialNumber = header.column.id === \"serialNumber\"\n const isCheckbox = header.column.id === \"select\"\n\n const columnDef = header.column.columnDef as GroupColumnDef<T>\n const columnFooter = columnDef.customFooter\n\n const hasContent =\n columnAgg || columnFooter || (isSerialNumber && shouldShowSerialTotal)\n\n if (!hasContent) {\n return (\n <TableCell\n key={`agg-${header.id}`}\n className={cn(\n \"relative px-0 py-0\",\n index < footerColCount - 1 && header.column.id !== lastCenterId && \"border-r\",\n compact && \"py-0\",\n isPinnedLeft && \"sticky left-0 z-30 bg-sidebar\",\n isPinnedRight && \"sticky right-0 z-30 bg-sidebar\",\n (isSerialNumber || isCheckbox) && \"sticky left-0 z-30 bg-sidebar\"\n )}\n style={{\n width: stickyWidth(header.getSize(), isPinnedLeft || isPinnedRight),\n minWidth: stickyWidth(header.getSize(), isPinnedLeft || isPinnedRight),\n ...getPinningStyles(header.column, enableColumnPinning),\n }}\n >\n <div className=\"absolute top-0 inset-x-0 h-px bg-border pointer-events-none\" />\n </TableCell>\n )\n }\n\n return (\n <TableCell\n key={`agg-${header.id}`}\n className={cn(\n \"relative px-2 py-2 font-semibold text-sm\",\n index < footerColCount - 1 && \"border-r\",\n compact && \"py-1\",\n isPinnedLeft && \"sticky left-0 z-30 bg-sidebar\",\n isPinnedRight && \"sticky right-0 z-30 bg-sidebar\",\n (isSerialNumber || isCheckbox) && \"sticky left-0 z-30 bg-sidebar\",\n columnFooter?.className\n )}\n style={{\n width: stickyWidth(header.getSize(), isPinnedLeft || isPinnedRight),\n minWidth: stickyWidth(header.getSize(), isPinnedLeft || isPinnedRight),\n ...getPinningStyles(header.column, enableColumnPinning),\n }}\n >\n {/* Sticky-safe top border (CSS border on sticky footer scrolls away) */}\n <div className=\"absolute top-0 inset-x-0 h-px bg-border pointer-events-none\" />\n {(() => {\n if (columnFooter?.content) {\n const content =\n typeof columnFooter.content === \"function\"\n ? columnFooter.content(table)\n : columnFooter.content\n return (\n <div\n className={cn(\n \"w-full h-full\",\n columnFooter.align === \"center\" && \"text-center\",\n columnFooter.align === \"right\" && \"text-right\",\n columnFooter.align === \"left\" && \"text-left\"\n )}\n >\n {content}\n </div>\n )\n }\n\n if (columnAgg) {\n return (\n <div className=\"flex flex-col gap-0.5 text-xs\">\n {Object.entries(columnAgg).map(([func, value]) => (\n <div\n key={func}\n className=\"flex justify-between items-center text-muted-foreground\"\n >\n <span className=\"text-xs capitalize\">{func}</span>\n <span className=\"font-medium text-foreground\">\n {aggregations?.[columnId]?.format?.(value, func as AggregationFunction) ??\n formatAggregationValue(func, value)}\n </span>\n </div>\n ))}\n </div>\n )\n }\n\n if (isSerialNumber && shouldShowSerialTotal) {\n return (\n <div className=\"text-muted-foreground text-xs text-center\">\n Total {table.getFilteredRowModel().rows.length}\n </div>\n )\n }\n\n return null\n })()}\n </TableCell>\n )\n })}\n </TableRow>\n </TableFooter>\n )\n}\n"],"mappings":"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","names":["clsx","twMerge","cn","inputs","jsx","TableFooter","className","props","jsx","cn","TableRow","TableCell","className","props","jsx","cn","getPinningStyles","column","enableColumnPinning","pinned","size","stickyWidth","isPinned","formatAggregationValue","func","value","jsx","jsxs","DataTableAggregationFooter","table","columnAggregations","aggregations","enableColumnPinning","enableRowSelection","showSerialNumbers","compact","hasColumnAggregations","hasCustomFooters","header","shouldShowSerialTotal","footerColCount","centerCols","c","lastCenterId","TableFooter","TableRow","index","columnId","columnAgg","isPinnedLeft","isPinnedRight","isSerialNumber","isCheckbox","columnFooter","TableCell","cn","stickyWidth","getPinningStyles","content","func","value","formatAggregationValue"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
"use strict";var k=Object.defineProperty;var oe=Object.getOwnPropertyDescriptor;var ne=Object.getOwnPropertyNames;var re=Object.prototype.hasOwnProperty;var ae=(o,n)=>{for(var r in n)k(o,r,{get:n[r],enumerable:!0})},ie=(o,n,r,s)=>{if(n&&typeof n=="object"||typeof n=="function")for(let d of ne(n))!re.call(o,d)&&d!==r&&k(o,d,{get:()=>n[d],enumerable:!(s=oe(n,d))||s.enumerable});return o};var se=o=>ie(k({},"__esModule",{value:!0}),o);var ue={};ae(ue,{DataTableHeaderRows:()=>le});module.exports=se(ue);var H=require("@tanstack/react-table"),a=require("lucide-react");var A=require("clsx"),E=require("tailwind-merge");function i(...o){return(0,E.twMerge)((0,A.clsx)(o))}var R=require("react/jsx-runtime");function V({className:o,...n}){return(0,R.jsx)("tr",{"data-slot":"table-row",className:i("hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors",o),...n})}function j({className:o,...n}){return(0,R.jsx)("th",{"data-slot":"table-head",className:i("text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap",o),...n})}var B=require("radix-ui"),W=require("class-variance-authority");var O=require("react/jsx-runtime"),de=(0,W.cva)("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",{variants:{variant:{default:"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",destructive:"bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",outline:"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 dark:focus-visible:border-ring",secondary:"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",ghost:"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",link:"text-primary underline-offset-4 hover:underline"},size:{default:"h-9 px-4 py-2 has-[>svg]:px-3",sm:"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",lg:"h-10 rounded-md px-6 has-[>svg]:px-4",icon:"size-9"}},defaultVariants:{variant:"default",size:"default"}});function F({className:o,variant:n,size:r,asChild:s=!1,...d}){let y=s?B.Slot.Slot:"button";return(0,O.jsx)(y,{"data-slot":"button",className:i(de({variant:n,size:r,className:o})),...d})}var m=require("radix-ui"),N=require("lucide-react");var l=require("react/jsx-runtime");function U({...o}){return(0,l.jsx)(m.DropdownMenu.Root,{"data-slot":"dropdown-menu",...o})}function q({...o}){return(0,l.jsx)(m.DropdownMenu.Trigger,{"data-slot":"dropdown-menu-trigger",...o})}function J({className:o,sideOffset:n=4,...r}){return(0,l.jsx)(m.DropdownMenu.Portal,{children:(0,l.jsx)(m.DropdownMenu.Content,{"data-slot":"dropdown-menu-content",sideOffset:n,className:i("bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) rounded-md border p-1 shadow-md",o),...r})})}function f({className:o,inset:n,variant:r="default",...s}){return(0,l.jsx)(m.DropdownMenu.Item,{"data-slot":"dropdown-menu-item","data-inset":n,"data-variant":r,className:i("cursor-pointer focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",o),...s})}function T({className:o,inset:n,...r}){return(0,l.jsx)(m.DropdownMenu.Label,{"data-slot":"dropdown-menu-label","data-inset":n,className:i("px-2 py-1.5 text-sm font-medium data-[inset]:pl-8",o),...r})}function I({className:o,...n}){return(0,l.jsx)(m.DropdownMenu.Separator,{"data-slot":"dropdown-menu-separator",className:i("bg-border -mx-1 my-1 h-px",o),...n})}function K(o,n){if(!n)return{};let r=o.getIsPinned();if(!r)return{};let s=o.getSize();return{position:"sticky",left:r==="left"?o.getStart("left"):void 0,right:r==="right"?o.getAfter("right"):void 0,width:s,minWidth:s,maxWidth:s,boxShadow:r==="right"&&o.getIsFirstColumn("right")?"inset 1px 0 0 0 var(--border)":void 0}}var z=(o,n)=>n||o!==150?o:"auto";var e=require("react/jsx-runtime");function le({table:o,aggregations:n,enableColumnPinning:r,enableColumnResizing:s,enableColumnVisibility:d,enableRowSelection:y,fixedCheckboxColumn:$,bordered:Q,compact:X,onPinColumn:C}){let L=o.getVisibleLeafColumns().filter(b=>!b.getIsPinned()),Y=L[L.length-1]?.id;return(0,e.jsx)(e.Fragment,{children:o.getHeaderGroups().map(b=>(0,e.jsx)(V,{className:"hover:bg-transparent",children:b.headers.map((t,Z)=>{let v=t.depth===0&&t.colSpan>1,P=r&&(t.column.getIsPinned()==="left"||t.column.id==="serialNumber"||t.column.id==="select"&&y),D=r&&t.column.getIsPinned()==="right",u=t.column.getCanSort(),M=r&&t.column.columnDef.enablePinning!==!1,_=t.column.id==="serialNumber",G=t.column.id==="select",w=_||G&&$,c=t.column.columnDef.headerAlign||"left",S=n&&n[t.column.id]?.enabled,h=d&&!w&&t.column.getCanHide(),x=t.column.columnDef.enableHeaderMenu!==!1&&(u||M&&!w||h),g=t.column.getIsSorted(),ee=t.column.columnDef.reserveMenuSpace===!0,te={left:"justify-start",center:"justify-center",right:"justify-end"}[c];return(0,e.jsxs)(j,{colSpan:t.colSpan,"data-col-id":v?void 0:t.column.id,className:i("group bg-sidebar px-0 font-semibold text-foreground",!X&&"py-2",Q&&Z<b.headers.length-1&&t.column.id!==Y&&"border-r","relative",P&&"sticky left-0 z-25 bg-sidebar/95",D&&"sticky right-0 z-25 bg-sidebar/95",(_||G)&&"sticky left-0 z-25 bg-sidebar/95",v?"text-center":"text-left"),style:{width:z(t.getSize(),P||D),minWidth:z(t.getSize(),P||D),...K(t.column,r)},children:[v?(0,e.jsxs)("div",{className:"flex justify-center items-center",children:[(0,H.flexRender)(t.column.columnDef.header,t.getContext()),S&&(0,e.jsx)(a.Calculator,{className:"ml-1 w-3 h-3 text-primary"})]}):(0,e.jsxs)("div",{className:i("relative flex items-center px-2 w-full",te,u&&"cursor-pointer select-none"),onClick:u?p=>{p.target.closest("button, a, input, select, [role=button], [role=checkbox]")||t.column.getToggleSortingHandler()?.(p)}:void 0,children:[(0,e.jsxs)("div",{className:i("flex items-center gap-1 min-w-0 max-w-full",g&&(c==="right"?"pl-6":"pr-6"),ee&&(c==="right"?x?"pl-12":"pl-6":x?"pr-12":"pr-6")),children:[S&&(0,e.jsx)(a.Calculator,{className:"mr-1 w-3 h-3 text-primary shrink-0"}),t.isPlaceholder?null:(0,e.jsx)("span",{className:"truncate",children:(0,H.flexRender)(t.column.columnDef.header,t.getContext())})]}),(x||u)&&(0,e.jsxs)("div",{className:i("absolute inset-y-0 flex items-center pointer-events-none",c==="right"?"left-0 pr-8 pl-1 flex-row-reverse":"right-0 pl-8 pr-1"),children:[(0,e.jsx)("div",{className:i("absolute inset-0 from-sidebar from-45% to-transparent",c==="right"?"bg-gradient-to-r":"bg-gradient-to-l","transition-opacity duration-200 ease-out","opacity-0 group-hover:opacity-100 group-has-[[data-state=open]]:opacity-100")}),u&&(0,e.jsx)("span",{className:"relative shrink-0",children:g?g==="asc"?(0,e.jsx)(a.ChevronUp,{className:"w-4 h-4"}):(0,e.jsx)(a.ChevronDown,{className:"w-4 h-4"}):(0,e.jsx)(a.ChevronsUpDown,{className:"w-3.5 h-3.5 opacity-0 group-hover:opacity-40 transition-opacity"})}),x&&(0,e.jsxs)(U,{children:[(0,e.jsx)(q,{asChild:!0,children:(0,e.jsx)(F,{variant:"ghost",size:"icon",tabIndex:-1,"aria-label":"Column options",onClick:p=>p.stopPropagation(),className:i("relative size-6 rounded-sm pointer-events-auto overflow-hidden","bg-sidebar hover:bg-border dark:bg-sidebar dark:hover:bg-accent","w-0 opacity-0 group-hover:w-5 group-hover:opacity-100",c==="right"?"mr-0":"ml-0",u&&(c==="right"?"group-hover:mr-0.5":"group-hover:ml-0.5"),"data-[state=open]:w-5 data-[state=open]:opacity-100",u&&(c==="right"?"data-[state=open]:mr-0.5":"data-[state=open]:ml-0.5"),"transition-all duration-200 ease-out"),children:(0,e.jsx)(a.MoreHorizontal,{className:"w-4 h-4"})})}),(0,e.jsxs)(J,{align:"end",className:"w-48",onClick:p=>p.stopPropagation(),children:[u&&(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(T,{children:"Sorting"}),(0,e.jsxs)(f,{onClick:()=>t.column.toggleSorting(!1),disabled:g==="asc",children:[(0,e.jsx)(a.ChevronUp,{className:"mr-2 w-4 h-4"}),"Sort Ascending"]}),(0,e.jsxs)(f,{onClick:()=>t.column.toggleSorting(!0),disabled:g==="desc",children:[(0,e.jsx)(a.ChevronDown,{className:"mr-2 w-4 h-4"}),"Sort Descending"]}),(0,e.jsxs)(f,{onClick:()=>t.column.clearSorting(),disabled:!g,children:[(0,e.jsx)(a.ChevronsUpDown,{className:"mr-2 w-4 h-4"}),"Clear Sort"]}),(M&&!w||h)&&(0,e.jsx)(I,{})]}),M&&!w&&(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(T,{children:"Pin Column"}),(0,e.jsxs)(f,{onClick:()=>C(t.column.id,"left"),disabled:t.column.getIsPinned()==="left",children:[(0,e.jsx)(a.MoveLeftIcon,{}),"Pin Left"]}),(0,e.jsxs)(f,{onClick:()=>C(t.column.id,"right"),disabled:t.column.getIsPinned()==="right",children:[(0,e.jsx)(a.MoveRightIcon,{}),"Pin Right"]}),(0,e.jsxs)(f,{onClick:()=>C(t.column.id,!1),disabled:!t.column.getIsPinned(),children:[(0,e.jsx)(a.PinOffIcon,{}),"Unpin"]}),h&&(0,e.jsx)(I,{})]}),h&&(0,e.jsxs)(f,{onClick:()=>t.column.toggleVisibility(!1),children:[(0,e.jsx)(a.EyeOff,{className:"mr-2 w-4 h-4"}),"Hide Column"]})]})]})]})]}),(0,e.jsx)("div",{className:i("absolute bottom-0 inset-x-0 pointer-events-none",S?"h-0.5 bg-primary/40":"h-px bg-border")}),s&&t.column.getCanResize()&&!v&&t.colSpan===1&&(0,e.jsx)("div",{className:"top-0 right-0 absolute hover:bg-primary opacity-0 hover:opacity-100 bg-border w-1 h-full transition-opacity cursor-col-resize select-none touch-none",onMouseDown:t.getResizeHandler(),onTouchStart:t.getResizeHandler(),onClick:p=>p.stopPropagation()})]},t.id)})},b.id))})}0&&(module.exports={DataTableHeaderRows});
|
|
3
|
+
//# sourceMappingURL=data-table-header.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/data/data-table/data-table-header.tsx","../../../../src/lib/utils.ts","../../../../src/components/ui/table.tsx","../../../../src/components/ui/button.tsx","../../../../src/components/ui/dropdown-menu.tsx","../../../../src/components/data/data-table/data-table-pinning.ts"],"sourcesContent":["import { flexRender, type Table } from \"@tanstack/react-table\"\nimport {\n ChevronUp,\n ChevronDown,\n ChevronsUpDown,\n EyeOff,\n MoreHorizontal,\n MoveLeftIcon,\n MoveRightIcon,\n PinOffIcon,\n Calculator,\n} from \"lucide-react\"\nimport { TableHead, TableRow } from \"../../ui/table.jsx\"\nimport { Button } from \"../../ui/button.jsx\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"../../ui/dropdown-menu.jsx\"\nimport { cn } from \"../../../lib/utils.js\"\nimport type { AggregationConfigMap, GroupColumnDef } from \"./data-table-types.js\"\nimport { getPinningStyles, stickyWidth } from \"./data-table-pinning.js\"\n\ninterface DataTableHeaderRowsProps<T> {\n table: Table<T>\n aggregations: AggregationConfigMap<T>\n enableColumnPinning: boolean\n enableColumnResizing: boolean\n enableColumnVisibility: boolean\n enableRowSelection: boolean\n fixedCheckboxColumn: boolean\n bordered: boolean\n compact: boolean\n onPinColumn: (columnId: string, side: \"left\" | \"right\" | false) => void\n}\n\n/** Column-header rows (sorting/pin menu, aggregation marker, sticky-safe borders, resizer). */\nexport function DataTableHeaderRows<T>({\n table,\n aggregations,\n enableColumnPinning,\n enableColumnResizing,\n enableColumnVisibility,\n enableRowSelection,\n fixedCheckboxColumn,\n bordered,\n compact,\n onPinColumn,\n}: DataTableHeaderRowsProps<T>) {\n // last center column drops border-r so it doesn't double the right-pinned separator\n const centerCols = table.getVisibleLeafColumns().filter((c) => !c.getIsPinned())\n const lastCenterId = centerCols[centerCols.length - 1]?.id\n\n return (\n <>\n {table.getHeaderGroups().map((headerGroup) => (\n <TableRow key={headerGroup.id} className=\"hover:bg-transparent\">\n {headerGroup.headers.map((header, index) => {\n const isGroupHeader = header.depth === 0 && header.colSpan > 1\n const isPinnedLeft =\n enableColumnPinning &&\n (header.column.getIsPinned() === \"left\" ||\n header.column.id === \"serialNumber\" ||\n (header.column.id === \"select\" && enableRowSelection))\n const isPinnedRight = enableColumnPinning && header.column.getIsPinned() === \"right\"\n const canSort = header.column.getCanSort()\n const canPin = enableColumnPinning && header.column.columnDef.enablePinning !== false\n const isSerialNumber = header.column.id === \"serialNumber\"\n const isCheckbox = header.column.id === \"select\"\n const alwaysPinned = isSerialNumber || (isCheckbox && fixedCheckboxColumn)\n const headerAlign = (header.column.columnDef as GroupColumnDef<T>).headerAlign || \"left\"\n const hasAggregation = aggregations && aggregations[header.column.id]?.enabled\n const canHide = enableColumnVisibility && !alwaysPinned && header.column.getCanHide()\n const menuAllowed = (header.column.columnDef as GroupColumnDef<T>).enableHeaderMenu !== false\n const hasMenu = menuAllowed && (canSort || (canPin && !alwaysPinned) || canHide)\n const sorted = header.column.getIsSorted()\n const reserveMenuSpace = (header.column.columnDef as GroupColumnDef<T>).reserveMenuSpace === true\n\n const flexJustify = {\n left: \"justify-start\",\n center: \"justify-center\",\n right: \"justify-end\",\n }[headerAlign]\n\n return (\n <TableHead\n key={header.id}\n colSpan={header.colSpan}\n data-col-id={!isGroupHeader ? header.column.id : undefined}\n className={cn(\n \"group bg-sidebar px-0 font-semibold text-foreground\",\n !compact && \"py-2\",\n bordered &&\n index < headerGroup.headers.length - 1 &&\n header.column.id !== lastCenterId &&\n \"border-r\",\n \"relative\",\n isPinnedLeft && \"sticky left-0 z-25 bg-sidebar/95\",\n isPinnedRight && \"sticky right-0 z-25 bg-sidebar/95\",\n (isSerialNumber || isCheckbox) && \"sticky left-0 z-25 bg-sidebar/95\",\n isGroupHeader ? \"text-center\" : \"text-left\"\n )}\n style={{\n width: stickyWidth(header.getSize(), isPinnedLeft || isPinnedRight),\n minWidth: stickyWidth(header.getSize(), isPinnedLeft || isPinnedRight),\n ...getPinningStyles(header.column, enableColumnPinning),\n }}\n >\n {isGroupHeader ? (\n <div className=\"flex justify-center items-center\">\n {flexRender(header.column.columnDef.header, header.getContext())}\n {hasAggregation && <Calculator className=\"ml-1 w-3 h-3 text-primary\" />}\n </div>\n ) : (\n <div\n className={cn(\"relative flex items-center px-2 w-full\", flexJustify, canSort && \"cursor-pointer select-none\")}\n onClick={canSort ? (e) => {\n // Custom (JSX) headers may hold their own controls — a click on one must not sort.\n if ((e.target as HTMLElement).closest(\"button, a, input, select, [role=button], [role=checkbox]\")) return\n header.column.getToggleSortingHandler()?.(e)\n } : undefined}\n >\n {/* sorted, or a column opted into reserveMenuSpace, reserves real space\n (deliberate user action / explicit opt-in — column may grow); everyone\n else's hover reserves nothing, the cluster is pure overlay */}\n <div className={cn(\n \"flex items-center gap-1 min-w-0 max-w-full\",\n sorted && (headerAlign === \"right\" ? \"pl-6\" : \"pr-6\"),\n reserveMenuSpace && (headerAlign === \"right\"\n ? (hasMenu ? \"pl-12\" : \"pl-6\")\n : (hasMenu ? \"pr-12\" : \"pr-6\")),\n )}>\n {hasAggregation && <Calculator className=\"mr-1 w-3 h-3 text-primary shrink-0\" />}\n {header.isPlaceholder ? null : (\n <span className=\"truncate\">\n {flexRender(header.column.columnDef.header, header.getContext())}\n </span>\n )}\n </div>\n {/* floating right cluster [sort chevron][⋯]: while sorted the title reserves\n pr-6 so it ellipses instead of running under the chevron, and the chevron\n sits at the right edge. On hover the ⋯ expands w-0→w-6, shifting the\n chevron left to make room; a gradient scrim fades the title out under the\n overlay. pointer-events-none keeps the whole area click-to-sort, only the\n button itself is interactive. */}\n {(hasMenu || canSort) && (\n <div className={cn(\n \"absolute inset-y-0 flex items-center pointer-events-none\",\n headerAlign === \"right\" ? \"left-0 pr-8 pl-1 flex-row-reverse\" : \"right-0 pl-8 pr-1\"\n )}>\n <div\n className={cn(\n \"absolute inset-0 from-sidebar from-45% to-transparent\",\n headerAlign === \"right\" ? \"bg-gradient-to-r\" : \"bg-gradient-to-l\",\n \"transition-opacity duration-200 ease-out\",\n \"opacity-0 group-hover:opacity-100 group-has-[[data-state=open]]:opacity-100\"\n )}\n />\n {canSort && (\n <span className=\"relative shrink-0\">\n {sorted ? (\n sorted === \"asc\" ? <ChevronUp className=\"w-4 h-4\" /> : <ChevronDown className=\"w-4 h-4\" />\n ) : (\n <ChevronsUpDown className=\"w-3.5 h-3.5 opacity-0 group-hover:opacity-40 transition-opacity\" />\n )}\n </span>\n )}\n {hasMenu && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n tabIndex={-1}\n aria-label=\"Column options\"\n onClick={(e) => e.stopPropagation()}\n className={cn(\n \"relative size-6 rounded-sm pointer-events-auto overflow-hidden\",\n \"bg-sidebar hover:bg-border dark:bg-sidebar dark:hover:bg-accent\",\n \"w-0 opacity-0 group-hover:w-5 group-hover:opacity-100\",\n headerAlign === \"right\" ? \"mr-0\" : \"ml-0\",\n canSort && (headerAlign === \"right\" ? \"group-hover:mr-0.5\" : \"group-hover:ml-0.5\"),\n \"data-[state=open]:w-5 data-[state=open]:opacity-100\",\n canSort && (headerAlign === \"right\" ? \"data-[state=open]:mr-0.5\" : \"data-[state=open]:ml-0.5\"),\n \"transition-all duration-200 ease-out\"\n )}\n >\n <MoreHorizontal className=\"w-4 h-4\" />\n </Button>\n </DropdownMenuTrigger>\n {/* content is portaled but React events still bubble through the\n component tree — without this, item clicks hit click-to-sort */}\n <DropdownMenuContent\n align=\"end\"\n className=\"w-48\"\n onClick={(e) => e.stopPropagation()}\n >\n {canSort && (\n <>\n <DropdownMenuLabel>Sorting</DropdownMenuLabel>\n <DropdownMenuItem\n onClick={() => header.column.toggleSorting(false)}\n disabled={sorted === \"asc\"}\n >\n <ChevronUp className=\"mr-2 w-4 h-4\" />\n Sort Ascending\n </DropdownMenuItem>\n <DropdownMenuItem\n onClick={() => header.column.toggleSorting(true)}\n disabled={sorted === \"desc\"}\n >\n <ChevronDown className=\"mr-2 w-4 h-4\" />\n Sort Descending\n </DropdownMenuItem>\n <DropdownMenuItem\n onClick={() => header.column.clearSorting()}\n disabled={!sorted}\n >\n <ChevronsUpDown className=\"mr-2 w-4 h-4\" />\n Clear Sort\n </DropdownMenuItem>\n {((canPin && !alwaysPinned) || canHide) && <DropdownMenuSeparator />}\n </>\n )}\n {canPin && !alwaysPinned && (\n <>\n <DropdownMenuLabel>Pin Column</DropdownMenuLabel>\n <DropdownMenuItem\n onClick={() => onPinColumn(header.column.id, \"left\")}\n disabled={header.column.getIsPinned() === \"left\"}\n >\n <MoveLeftIcon />\n Pin Left\n </DropdownMenuItem>\n <DropdownMenuItem\n onClick={() => onPinColumn(header.column.id, \"right\")}\n disabled={header.column.getIsPinned() === \"right\"}\n >\n <MoveRightIcon />\n Pin Right\n </DropdownMenuItem>\n <DropdownMenuItem\n onClick={() => onPinColumn(header.column.id, false)}\n disabled={!header.column.getIsPinned()}\n >\n <PinOffIcon />\n Unpin\n </DropdownMenuItem>\n {canHide && <DropdownMenuSeparator />}\n </>\n )}\n {canHide && (\n <DropdownMenuItem onClick={() => header.column.toggleVisibility(false)}>\n <EyeOff className=\"mr-2 w-4 h-4\" />\n Hide Column\n </DropdownMenuItem>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </div>\n )}\n </div>\n )}\n {/* border drawn in-cell (a border on the sticky header scrolls away) */}\n <div\n className={cn(\n \"absolute bottom-0 inset-x-0 pointer-events-none\",\n hasAggregation ? \"h-0.5 bg-primary/40\" : \"h-px bg-border\"\n )}\n />\n {/* Column Resizer */}\n {enableColumnResizing &&\n header.column.getCanResize() &&\n !isGroupHeader &&\n header.colSpan === 1 && (\n <div\n className=\"top-0 right-0 absolute hover:bg-primary opacity-0 hover:opacity-100 bg-border w-1 h-full transition-opacity cursor-col-resize select-none touch-none\"\n onMouseDown={header.getResizeHandler()}\n onTouchStart={header.getResizeHandler()}\n onClick={(e) => e.stopPropagation()}\n />\n )}\n </TableHead>\n )\n })}\n </TableRow>\n ))}\n </>\n )\n}\n","import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}","import * as React from \"react\"\n\nimport { cn } from \"../../lib/utils.js\"\n\nfunction Table({ className, ...props }: React.ComponentProps<\"table\">) {\n return (\n <div\n data-slot=\"table-container\"\n className=\"relative w-full h-full max-h-full overflow-auto\"\n >\n <table\n data-slot=\"table\"\n className={cn(\"w-full caption-bottom text-sm\", className)}\n {...props}\n />\n </div>\n )\n}\n\nfunction TableHeader({ className, ...props }: React.ComponentProps<\"thead\">) {\n return (\n <thead\n data-slot=\"table-header\"\n className={cn(\"[&_tr]:border-b\", className)}\n {...props}\n />\n )\n}\n\nfunction TableBody({ className, ...props }: React.ComponentProps<\"tbody\">) {\n return (\n <tbody\n data-slot=\"table-body\"\n className={cn(\"[&_tr:last-child]:border-0\", className)}\n {...props}\n />\n )\n}\n\nfunction TableFooter({ className, ...props }: React.ComponentProps<\"tfoot\">) {\n return (\n <tfoot\n data-slot=\"table-footer\"\n className={cn(\n \"bg-muted/50 border-t font-medium [&>tr]:last:border-b-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableRow({ className, ...props }: React.ComponentProps<\"tr\">) {\n return (\n <tr\n data-slot=\"table-row\"\n className={cn(\n \"hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableHead({ className, ...props }: React.ComponentProps<\"th\">) {\n return (\n <th\n data-slot=\"table-head\"\n className={cn(\n \"text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableCell({ className, ...props }: React.ComponentProps<\"td\">) {\n return (\n <td\n data-slot=\"table-cell\"\n className={cn(\n \"p-2 align-middle whitespace-nowrap\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableCaption({\n className,\n ...props\n}: React.ComponentProps<\"caption\">) {\n return (\n <caption\n data-slot=\"table-caption\"\n className={cn(\"text-muted-foreground mt-4 text-sm\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n}\n","import * as React from \"react\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../../lib/utils.js\"\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n outline:\n \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 dark:focus-visible:border-ring\",\n secondary:\n \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n ghost:\n \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n icon: \"size-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Button({\n className,\n variant,\n size,\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean\n }) {\n const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n return (\n <Comp\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Button, buttonVariants }\n","import * as React from \"react\"\nimport { DropdownMenu as DropdownMenuPrimitive } from \"radix-ui\"\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\"\n\nimport { cn } from \"../../lib/utils.js\"\n\nfunction DropdownMenu({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />\n}\n\nfunction DropdownMenuPortal({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n return (\n <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n )\n}\n\nfunction DropdownMenuTrigger({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n return (\n <DropdownMenuPrimitive.Trigger\n data-slot=\"dropdown-menu-trigger\"\n {...props}\n />\n )\n}\n\nfunction DropdownMenuContent({\n className,\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n data-slot=\"dropdown-menu-content\"\n sideOffset={sideOffset}\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) rounded-md border p-1 shadow-md\",\n className\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n )\n}\n\nfunction DropdownMenuGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n return (\n <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n )\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean\n variant?: \"default\" | \"destructive\"\n}) {\n return (\n <DropdownMenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset}\n data-variant={variant}\n className={cn(\n \"cursor-pointer focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n checked={checked}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n )\n}\n\nfunction DropdownMenuRadioGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n return (\n <DropdownMenuPrimitive.RadioGroup\n data-slot=\"dropdown-menu-radio-group\"\n {...props}\n />\n )\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n return (\n <DropdownMenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CircleIcon className=\"size-2 fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n )\n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean\n}) {\n return (\n <DropdownMenuPrimitive.Label\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn(\n \"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n return (\n <DropdownMenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn(\n \"text-muted-foreground ml-auto text-xs tracking-widest\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuSub({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />\n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean\n}) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto size-4\" />\n </DropdownMenuPrimitive.SubTrigger>\n )\n}\n\nfunction DropdownMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n return (\n <DropdownMenuPrimitive.SubContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n DropdownMenu,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n}\n","import type { Column, ColumnPinningState, Table } from \"@tanstack/react-table\"\nimport type { CSSProperties } from \"react\"\nimport type { GroupColumnDef } from \"./data-table-types.js\"\n\n/**\n * Sticky styles for a pinned column cell — TanStack's official pinning pattern\n * (`getStart`/`getAfter` offsets; column locked to `size` so offsets stay true; 1px inset\n * shadow separates the first right-pinned column).\n */\nexport function getPinningStyles(\n column: Column<any, unknown>,\n enableColumnPinning: boolean,\n): CSSProperties {\n if (!enableColumnPinning) return {}\n const pinned = column.getIsPinned()\n if (!pinned) return {}\n\n const size = column.getSize()\n\n return {\n position: \"sticky\",\n left: pinned === \"left\" ? column.getStart(\"left\") : undefined,\n right: pinned === \"right\" ? column.getAfter(\"right\") : undefined,\n width: size,\n minWidth: size,\n maxWidth: size,\n // box-shadow (not border) stays put on sticky cells; marks the right-pinned group's left edge\n boxShadow:\n pinned === \"right\" && column.getIsFirstColumn(\"right\")\n ? \"inset 1px 0 0 0 var(--border)\"\n : undefined,\n }\n}\n\n/** Width for a non-pinned cell: explicit size or auto (150 = TanStack default = auto). */\nexport const stickyWidth = (size: number, isPinned: boolean): number | string =>\n isPinned ? size : size !== 150 ? size : \"auto\"\n\n/**\n * Resolve `defaultPin`/`pinIndex` off the raw column defs (recursing into group columns) into\n * ordered left/right id lists for the table's initial pinning state. Lower `pinIndex` sits\n * closer to the outer edge; columns without a finite `pinIndex` keep declaration order.\n * Defensive against bad input (duplicate/malformed ids, non-numeric `pinIndex`, an invalid\n * `defaultPin` value slipping through from untyped JS callers): each is skipped or falls back\n * rather than corrupting the pinning state.\n */\nexport function collectDefaultPinned<T>(columns: GroupColumnDef<T>[]): { left: string[]; right: string[] } {\n type Entry = { id: string; order: number }\n const left: Entry[] = []\n const right: Entry[] = []\n const seen = new Set<string>()\n\n const walk = (cols: GroupColumnDef<T>[]) => {\n cols.forEach((col, index) => {\n const rawId = (col as any).id ?? (col as any).accessorKey\n const id = rawId != null ? String(rawId) : \"\"\n if (id && (col.defaultPin === \"left\" || col.defaultPin === \"right\") && !seen.has(id)) {\n seen.add(id)\n const order = Number.isFinite(col.pinIndex as number) ? (col.pinIndex as number) : index\n ;(col.defaultPin === \"left\" ? left : right).push({ id, order })\n }\n if (col.columns) walk(col.columns)\n })\n }\n walk(columns)\n\n // stable sort (spec-guaranteed since ES2019): equal/duplicate `order` values keep declaration order\n const toIds = (entries: Entry[]) => entries.sort((a, b) => a.order - b.order).map((e) => e.id)\n return { left: toIds(left), right: toIds(right) }\n}\n\n/** Re-assert the always-left-pinned helper columns on every pinning change. */\nexport function enforceAlwaysPinned(next: ColumnPinningState, always: string[]): ColumnPinningState {\n return {\n left: [...always, ...(next.left ?? []).filter((id) => !always.includes(id))],\n right: (next.right ?? []).filter((id) => !always.includes(id)),\n }\n}\n\n/**\n * Pin/unpin a column. Captures the column's live rendered width on pin (so it doesn't jump to\n * its declared `size`) and drops the override on unpin.\n */\nexport function pinColumn<T>(\n table: Table<T>,\n columnId: string,\n side: \"left\" | \"right\" | false,\n opts: { container: HTMLElement | null; alwaysPinnedLeft: string[] },\n) {\n if (side === false) {\n table.setColumnSizing((prev) => {\n const next = { ...prev }\n delete next[columnId]\n return next\n })\n } else {\n const headerEl = opts.container?.querySelector<HTMLElement>(`[data-col-id=\"${columnId}\"]`)\n const width = headerEl ? Math.round(headerEl.getBoundingClientRect().width) : 0\n if (width > 0) table.setColumnSizing((prev) => ({ ...prev, [columnId]: width }))\n }\n\n const { alwaysPinnedLeft } = opts\n const current = table.getState().columnPinning\n const newPinning = {\n left: (current.left ?? []).filter((id) => alwaysPinnedLeft.includes(id)),\n right: [...(current.right ?? [])],\n }\n\n if (side === \"right\") {\n if (!newPinning.right.includes(columnId)) newPinning.right.push(columnId)\n } else if (side === \"left\") {\n newPinning.right = newPinning.right.filter((id) => id !== columnId)\n if (!newPinning.left.includes(columnId) && !alwaysPinnedLeft.includes(columnId)) {\n newPinning.left.push(columnId)\n }\n } else {\n newPinning.left = newPinning.left.filter((id) => id !== columnId)\n newPinning.right = newPinning.right.filter((id) => id !== columnId)\n }\n\n table.setColumnPinning(newPinning)\n}\n"],"mappings":"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","names":["data_table_header_exports","__export","DataTableHeaderRows","__toCommonJS","import_react_table","import_lucide_react","import_clsx","import_tailwind_merge","cn","inputs","import_jsx_runtime","TableRow","className","props","cn","TableHead","import_radix_ui","import_class_variance_authority","import_jsx_runtime","buttonVariants","Button","className","variant","size","asChild","props","Comp","SlotPrimitive","cn","import_radix_ui","import_lucide_react","import_jsx_runtime","DropdownMenu","props","DropdownMenuPrimitive","DropdownMenuTrigger","props","DropdownMenuPrimitive","DropdownMenuContent","className","sideOffset","cn","DropdownMenuItem","className","inset","variant","props","DropdownMenuPrimitive","cn","DropdownMenuLabel","className","inset","props","DropdownMenuPrimitive","cn","DropdownMenuSeparator","getPinningStyles","column","enableColumnPinning","pinned","size","stickyWidth","isPinned","import_jsx_runtime","DataTableHeaderRows","table","aggregations","enableColumnPinning","enableColumnResizing","enableColumnVisibility","enableRowSelection","fixedCheckboxColumn","bordered","compact","onPinColumn","centerCols","c","lastCenterId","headerGroup","TableRow","header","index","isGroupHeader","isPinnedLeft","isPinnedRight","canSort","canPin","isSerialNumber","isCheckbox","alwaysPinned","headerAlign","hasAggregation","canHide","hasMenu","sorted","reserveMenuSpace","flexJustify","TableHead","cn","stickyWidth","getPinningStyles","e","DropdownMenu","DropdownMenuTrigger","Button","DropdownMenuContent","DropdownMenuLabel","DropdownMenuItem","DropdownMenuSeparator"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { Table } from '@tanstack/react-table';
|
|
3
|
+
import { AggregationConfigMap } from './data-table-types.cjs';
|
|
4
|
+
import 'lucide-react';
|
|
5
|
+
import './data-table-persist.cjs';
|
|
6
|
+
import './data-table-export.cjs';
|
|
7
|
+
|
|
8
|
+
interface DataTableHeaderRowsProps<T> {
|
|
9
|
+
table: Table<T>;
|
|
10
|
+
aggregations: AggregationConfigMap<T>;
|
|
11
|
+
enableColumnPinning: boolean;
|
|
12
|
+
enableColumnResizing: boolean;
|
|
13
|
+
enableColumnVisibility: boolean;
|
|
14
|
+
enableRowSelection: boolean;
|
|
15
|
+
fixedCheckboxColumn: boolean;
|
|
16
|
+
bordered: boolean;
|
|
17
|
+
compact: boolean;
|
|
18
|
+
onPinColumn: (columnId: string, side: "left" | "right" | false) => void;
|
|
19
|
+
}
|
|
20
|
+
/** Column-header rows (sorting/pin menu, aggregation marker, sticky-safe borders, resizer). */
|
|
21
|
+
declare function DataTableHeaderRows<T>({ table, aggregations, enableColumnPinning, enableColumnResizing, enableColumnVisibility, enableRowSelection, fixedCheckboxColumn, bordered, compact, onPinColumn, }: DataTableHeaderRowsProps<T>): react_jsx_runtime.JSX.Element;
|
|
22
|
+
|
|
23
|
+
export { DataTableHeaderRows };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { Table } from '@tanstack/react-table';
|
|
3
|
+
import { AggregationConfigMap } from './data-table-types.js';
|
|
4
|
+
import 'lucide-react';
|
|
5
|
+
import './data-table-persist.js';
|
|
6
|
+
import './data-table-export.js';
|
|
7
|
+
|
|
8
|
+
interface DataTableHeaderRowsProps<T> {
|
|
9
|
+
table: Table<T>;
|
|
10
|
+
aggregations: AggregationConfigMap<T>;
|
|
11
|
+
enableColumnPinning: boolean;
|
|
12
|
+
enableColumnResizing: boolean;
|
|
13
|
+
enableColumnVisibility: boolean;
|
|
14
|
+
enableRowSelection: boolean;
|
|
15
|
+
fixedCheckboxColumn: boolean;
|
|
16
|
+
bordered: boolean;
|
|
17
|
+
compact: boolean;
|
|
18
|
+
onPinColumn: (columnId: string, side: "left" | "right" | false) => void;
|
|
19
|
+
}
|
|
20
|
+
/** Column-header rows (sorting/pin menu, aggregation marker, sticky-safe borders, resizer). */
|
|
21
|
+
declare function DataTableHeaderRows<T>({ table, aggregations, enableColumnPinning, enableColumnResizing, enableColumnVisibility, enableRowSelection, fixedCheckboxColumn, bordered, compact, onPinColumn, }: DataTableHeaderRowsProps<T>): react_jsx_runtime.JSX.Element;
|
|
22
|
+
|
|
23
|
+
export { DataTableHeaderRows };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
import{flexRender as W}from"@tanstack/react-table";import{ChevronUp as F,ChevronDown as O,ChevronsUpDown as U,EyeOff as ie,MoreHorizontal as se,MoveLeftIcon as de,MoveRightIcon as le,PinOffIcon as ue,Calculator as q}from"lucide-react";import{clsx as ee}from"clsx";import{twMerge as te}from"tailwind-merge";function r(...t){return te(ee(t))}import{jsx as G}from"react/jsx-runtime";function L({className:t,...n}){return G("tr",{"data-slot":"table-row",className:r("hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors",t),...n})}function _({className:t,...n}){return G("th",{"data-slot":"table-head",className:r("text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap",t),...n})}import{Slot as oe}from"radix-ui";import{cva as ne}from"class-variance-authority";import{jsx as ae}from"react/jsx-runtime";var re=ne("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",{variants:{variant:{default:"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",destructive:"bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",outline:"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 dark:focus-visible:border-ring",secondary:"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",ghost:"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",link:"text-primary underline-offset-4 hover:underline"},size:{default:"h-9 px-4 py-2 has-[>svg]:px-3",sm:"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",lg:"h-10 rounded-md px-6 has-[>svg]:px-4",icon:"size-9"}},defaultVariants:{variant:"default",size:"default"}});function A({className:t,variant:n,size:a,asChild:s=!1,...x}){let y=s?oe.Slot:"button";return ae(y,{"data-slot":"button",className:r(re({variant:n,size:a,className:t})),...x})}import{DropdownMenu as p}from"radix-ui";import{CheckIcon as Me,ChevronRightIcon as Se,CircleIcon as ke}from"lucide-react";import{jsx as m,jsxs as Te}from"react/jsx-runtime";function E({...t}){return m(p.Root,{"data-slot":"dropdown-menu",...t})}function V({...t}){return m(p.Trigger,{"data-slot":"dropdown-menu-trigger",...t})}function j({className:t,sideOffset:n=4,...a}){return m(p.Portal,{children:m(p.Content,{"data-slot":"dropdown-menu-content",sideOffset:n,className:r("bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) rounded-md border p-1 shadow-md",t),...a})})}function c({className:t,inset:n,variant:a="default",...s}){return m(p.Item,{"data-slot":"dropdown-menu-item","data-inset":n,"data-variant":a,className:r("cursor-pointer focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",t),...s})}function k({className:t,inset:n,...a}){return m(p.Label,{"data-slot":"dropdown-menu-label","data-inset":n,className:r("px-2 py-1.5 text-sm font-medium data-[inset]:pl-8",t),...a})}function R({className:t,...n}){return m(p.Separator,{"data-slot":"dropdown-menu-separator",className:r("bg-border -mx-1 my-1 h-px",t),...n})}function B(t,n){if(!n)return{};let a=t.getIsPinned();if(!a)return{};let s=t.getSize();return{position:"sticky",left:a==="left"?t.getStart("left"):void 0,right:a==="right"?t.getAfter("right"):void 0,width:s,minWidth:s,maxWidth:s,boxShadow:a==="right"&&t.getIsFirstColumn("right")?"inset 1px 0 0 0 var(--border)":void 0}}var N=(t,n)=>n||t!==150?t:"auto";import{Fragment as T,jsx as o,jsxs as i}from"react/jsx-runtime";function je({table:t,aggregations:n,enableColumnPinning:a,enableColumnResizing:s,enableColumnVisibility:x,enableRowSelection:y,fixedCheckboxColumn:J,bordered:K,compact:$,onPinColumn:C}){let I=t.getVisibleLeafColumns().filter(g=>!g.getIsPinned()),Q=I[I.length-1]?.id;return o(T,{children:t.getHeaderGroups().map(g=>o(L,{className:"hover:bg-transparent",children:g.headers.map((e,X)=>{let b=e.depth===0&&e.colSpan>1,P=a&&(e.column.getIsPinned()==="left"||e.column.id==="serialNumber"||e.column.id==="select"&&y),D=a&&e.column.getIsPinned()==="right",d=e.column.getCanSort(),M=a&&e.column.columnDef.enablePinning!==!1,z=e.column.id==="serialNumber",H=e.column.id==="select",v=z||H&&J,l=e.column.columnDef.headerAlign||"left",S=n&&n[e.column.id]?.enabled,w=x&&!v&&e.column.getCanHide(),h=e.column.columnDef.enableHeaderMenu!==!1&&(d||M&&!v||w),f=e.column.getIsSorted(),Y=e.column.columnDef.reserveMenuSpace===!0,Z={left:"justify-start",center:"justify-center",right:"justify-end"}[l];return i(_,{colSpan:e.colSpan,"data-col-id":b?void 0:e.column.id,className:r("group bg-sidebar px-0 font-semibold text-foreground",!$&&"py-2",K&&X<g.headers.length-1&&e.column.id!==Q&&"border-r","relative",P&&"sticky left-0 z-25 bg-sidebar/95",D&&"sticky right-0 z-25 bg-sidebar/95",(z||H)&&"sticky left-0 z-25 bg-sidebar/95",b?"text-center":"text-left"),style:{width:N(e.getSize(),P||D),minWidth:N(e.getSize(),P||D),...B(e.column,a)},children:[b?i("div",{className:"flex justify-center items-center",children:[W(e.column.columnDef.header,e.getContext()),S&&o(q,{className:"ml-1 w-3 h-3 text-primary"})]}):i("div",{className:r("relative flex items-center px-2 w-full",Z,d&&"cursor-pointer select-none"),onClick:d?u=>{u.target.closest("button, a, input, select, [role=button], [role=checkbox]")||e.column.getToggleSortingHandler()?.(u)}:void 0,children:[i("div",{className:r("flex items-center gap-1 min-w-0 max-w-full",f&&(l==="right"?"pl-6":"pr-6"),Y&&(l==="right"?h?"pl-12":"pl-6":h?"pr-12":"pr-6")),children:[S&&o(q,{className:"mr-1 w-3 h-3 text-primary shrink-0"}),e.isPlaceholder?null:o("span",{className:"truncate",children:W(e.column.columnDef.header,e.getContext())})]}),(h||d)&&i("div",{className:r("absolute inset-y-0 flex items-center pointer-events-none",l==="right"?"left-0 pr-8 pl-1 flex-row-reverse":"right-0 pl-8 pr-1"),children:[o("div",{className:r("absolute inset-0 from-sidebar from-45% to-transparent",l==="right"?"bg-gradient-to-r":"bg-gradient-to-l","transition-opacity duration-200 ease-out","opacity-0 group-hover:opacity-100 group-has-[[data-state=open]]:opacity-100")}),d&&o("span",{className:"relative shrink-0",children:f?f==="asc"?o(F,{className:"w-4 h-4"}):o(O,{className:"w-4 h-4"}):o(U,{className:"w-3.5 h-3.5 opacity-0 group-hover:opacity-40 transition-opacity"})}),h&&i(E,{children:[o(V,{asChild:!0,children:o(A,{variant:"ghost",size:"icon",tabIndex:-1,"aria-label":"Column options",onClick:u=>u.stopPropagation(),className:r("relative size-6 rounded-sm pointer-events-auto overflow-hidden","bg-sidebar hover:bg-border dark:bg-sidebar dark:hover:bg-accent","w-0 opacity-0 group-hover:w-5 group-hover:opacity-100",l==="right"?"mr-0":"ml-0",d&&(l==="right"?"group-hover:mr-0.5":"group-hover:ml-0.5"),"data-[state=open]:w-5 data-[state=open]:opacity-100",d&&(l==="right"?"data-[state=open]:mr-0.5":"data-[state=open]:ml-0.5"),"transition-all duration-200 ease-out"),children:o(se,{className:"w-4 h-4"})})}),i(j,{align:"end",className:"w-48",onClick:u=>u.stopPropagation(),children:[d&&i(T,{children:[o(k,{children:"Sorting"}),i(c,{onClick:()=>e.column.toggleSorting(!1),disabled:f==="asc",children:[o(F,{className:"mr-2 w-4 h-4"}),"Sort Ascending"]}),i(c,{onClick:()=>e.column.toggleSorting(!0),disabled:f==="desc",children:[o(O,{className:"mr-2 w-4 h-4"}),"Sort Descending"]}),i(c,{onClick:()=>e.column.clearSorting(),disabled:!f,children:[o(U,{className:"mr-2 w-4 h-4"}),"Clear Sort"]}),(M&&!v||w)&&o(R,{})]}),M&&!v&&i(T,{children:[o(k,{children:"Pin Column"}),i(c,{onClick:()=>C(e.column.id,"left"),disabled:e.column.getIsPinned()==="left",children:[o(de,{}),"Pin Left"]}),i(c,{onClick:()=>C(e.column.id,"right"),disabled:e.column.getIsPinned()==="right",children:[o(le,{}),"Pin Right"]}),i(c,{onClick:()=>C(e.column.id,!1),disabled:!e.column.getIsPinned(),children:[o(ue,{}),"Unpin"]}),w&&o(R,{})]}),w&&i(c,{onClick:()=>e.column.toggleVisibility(!1),children:[o(ie,{className:"mr-2 w-4 h-4"}),"Hide Column"]})]})]})]})]}),o("div",{className:r("absolute bottom-0 inset-x-0 pointer-events-none",S?"h-0.5 bg-primary/40":"h-px bg-border")}),s&&e.column.getCanResize()&&!b&&e.colSpan===1&&o("div",{className:"top-0 right-0 absolute hover:bg-primary opacity-0 hover:opacity-100 bg-border w-1 h-full transition-opacity cursor-col-resize select-none touch-none",onMouseDown:e.getResizeHandler(),onTouchStart:e.getResizeHandler(),onClick:u=>u.stopPropagation()})]},e.id)})},g.id))})}export{je as DataTableHeaderRows};
|
|
3
|
+
//# sourceMappingURL=data-table-header.js.map
|