@xeplr/ui-table 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,131 @@
1
+ import { useMemo, useRef, useState } from 'react';
2
+ import {
3
+ useReactTable,
4
+ getCoreRowModel,
5
+ getFilteredRowModel,
6
+ getSortedRowModel,
7
+ getPaginationRowModel,
8
+ getFacetedRowModel,
9
+ getFacetedUniqueValues,
10
+ createColumnHelper
11
+ } from '@tanstack/react-table';
12
+ import { detectTypes, TYPES } from './detectTypes.js';
13
+ import { stringFilterFn } from './filters/StringFilter.jsx';
14
+ import { numberFilterFn } from './filters/NumberFilter.jsx';
15
+ import { dateFilterFn } from './filters/DateFilter.jsx';
16
+ import { booleanFilterFn } from './filters/BooleanFilter.jsx';
17
+
18
+ var filterFnMap = {
19
+ [TYPES.STRING]: stringFilterFn,
20
+ [TYPES.NUMBER]: numberFilterFn,
21
+ [TYPES.DATE]: dateFilterFn,
22
+ [TYPES.BOOLEAN]: booleanFilterFn
23
+ };
24
+
25
+ var columnHelper = createColumnHelper();
26
+
27
+ /**
28
+ * Hook that wires TanStack Table with auto-detected column types and smart filters.
29
+ *
30
+ * @param {object} options
31
+ * @param {Array<object>} options.data - Row array
32
+ * @param {Array<object>} options.columns - [{ accessor, header, dataType?, cell? }]
33
+ * @param {number} [options.minDetectionRows] - Min samples for confident detection (default: 10)
34
+ * @param {number} [options.pageSize] - Rows per page (default: 20)
35
+ * @param {boolean} [options.enableSorting] - Default: true
36
+ * @param {boolean} [options.enableFiltering] - Default: true
37
+ * @param {boolean} [options.enablePagination] - Default: true
38
+ *
39
+ * @returns {{ table, detectedTypes: Map, resetFilters: Function, resetSorting: Function }}
40
+ */
41
+ export default function useTableController(options) {
42
+ var data = options.data || [];
43
+ var columns = options.columns || [];
44
+ var minDetectionRows = options.minDetectionRows ?? 10;
45
+ var pageSize = options.pageSize ?? 20;
46
+ var enableSorting = options.enableSorting !== false;
47
+ var enableFiltering = options.enableFiltering !== false;
48
+ var enablePagination = options.enablePagination !== false;
49
+
50
+ // ── Type detection with memoization ──
51
+ var detectionRef = useRef({ types: null, confident: false, dataRef: null });
52
+
53
+ var detectedTypes = useMemo(function() {
54
+ var cached = detectionRef.current;
55
+
56
+ // Reuse cached types if detection was confident and data reference hasn't changed
57
+ if (cached.types && cached.confident && cached.dataRef === data) {
58
+ return cached.types;
59
+ }
60
+
61
+ // Reuse if confident even with new data reference (types don't change)
62
+ if (cached.types && cached.confident) {
63
+ return cached.types;
64
+ }
65
+
66
+ // Run detection
67
+ var result = detectTypes(data, columns, minDetectionRows);
68
+ detectionRef.current = { types: result.types, confident: result.confident, dataRef: data };
69
+ return result.types;
70
+ }, [data, columns, minDetectionRows]);
71
+
72
+ // ── Build TanStack column defs ──
73
+ var tanstackColumns = useMemo(function() {
74
+ return columns.map(function(col) {
75
+ var type = detectedTypes.get(col.accessor) || TYPES.STRING;
76
+ var filterFn = filterFnMap[type] || stringFilterFn;
77
+
78
+ var colDef = {
79
+ header: col.header || col.accessor,
80
+ filterFn: filterFn,
81
+ meta: { dataType: type, cellStyle: col.cellStyle || null },
82
+ enableSorting: col.enableSorting !== false,
83
+ enableColumnFilter: col.enableColumnFilter !== false
84
+ };
85
+ if (col.cell) colDef.cell = col.cell;
86
+ return columnHelper.accessor(col.accessor, colDef);
87
+ });
88
+ }, [columns, detectedTypes]);
89
+
90
+ // ── Table state ──
91
+ var [sorting, setSorting] = useState([]);
92
+ var [columnFilters, setColumnFilters] = useState([]);
93
+ var [pagination, setPagination] = useState({ pageIndex: 0, pageSize: pageSize });
94
+
95
+ // ── TanStack table instance ──
96
+ var table = useReactTable({
97
+ data: data,
98
+ columns: tanstackColumns,
99
+ state: {
100
+ sorting: sorting,
101
+ columnFilters: columnFilters,
102
+ pagination: pagination
103
+ },
104
+ onSortingChange: setSorting,
105
+ onColumnFiltersChange: setColumnFilters,
106
+ onPaginationChange: setPagination,
107
+ getCoreRowModel: getCoreRowModel(),
108
+ getFilteredRowModel: enableFiltering ? getFilteredRowModel() : undefined,
109
+ getSortedRowModel: enableSorting ? getSortedRowModel() : undefined,
110
+ getPaginationRowModel: enablePagination ? getPaginationRowModel() : undefined,
111
+ getFacetedRowModel: getFacetedRowModel(),
112
+ getFacetedUniqueValues: getFacetedUniqueValues(),
113
+ enableSorting: enableSorting,
114
+ enableFilters: enableFiltering
115
+ });
116
+
117
+ function resetFilters() {
118
+ setColumnFilters([]);
119
+ }
120
+
121
+ function resetSorting() {
122
+ setSorting([]);
123
+ }
124
+
125
+ return {
126
+ table: table,
127
+ detectedTypes: detectedTypes,
128
+ resetFilters: resetFilters,
129
+ resetSorting: resetSorting
130
+ };
131
+ }