@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.
- package/LICENSE +21 -0
- package/package.json +17 -0
- package/src/XeplrTable.jsx +332 -0
- package/src/actions/ActionsCell.jsx +75 -0
- package/src/actions/ChildTable.jsx +159 -0
- package/src/actions/RecordDetail.jsx +213 -0
- package/src/actions/RecordModal.jsx +159 -0
- package/src/buildChangeSet.js +126 -0
- package/src/detectTypes.js +102 -0
- package/src/filters/BooleanFilter.jsx +66 -0
- package/src/filters/DateFilter.jsx +75 -0
- package/src/filters/FilterWrapper.jsx +66 -0
- package/src/filters/NumberFilter.jsx +105 -0
- package/src/filters/StringFilter.jsx +142 -0
- package/src/index.js +32 -0
- package/src/operators.js +113 -0
- package/src/resolveCellStyle.js +252 -0
- package/src/useActionsController.js +453 -0
- package/src/useTableController.js +131 -0
- package/src/xeplr-table.css +913 -0
|
@@ -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
|
+
}
|