@xeplr/ui-table 1.0.0 → 1.0.2
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 +151 -0
- package/package.json +21 -5
- package/src/CellZoom.jsx +77 -0
- package/src/XeplrTable.jsx +349 -25
- package/src/actions/ActionsCell.jsx +36 -1
- package/src/columnWidths.js +333 -0
- package/src/filters/FilterWrapper.jsx +79 -30
- package/src/index.js +18 -0
- package/src/renderers/_helpers.js +43 -0
- package/src/renderers/avatarName.jsx +31 -0
- package/src/renderers/currency.jsx +25 -0
- package/src/renderers/dateDisplay.jsx +38 -0
- package/src/renderers/index.js +22 -0
- package/src/renderers/link.jsx +24 -0
- package/src/renderers/memberChips.jsx +35 -0
- package/src/renderers/statusBadge.jsx +15 -0
- package/src/renderers/tags.jsx +23 -0
- package/src/renderers/twoLine.jsx +16 -0
- package/src/tableStyles.js +236 -0
- package/src/useColumnWidths.js +280 -0
- package/src/useTableController.js +74 -7
- package/src/xeplr-table.css +399 -253
|
@@ -14,6 +14,7 @@ import { stringFilterFn } from './filters/StringFilter.jsx';
|
|
|
14
14
|
import { numberFilterFn } from './filters/NumberFilter.jsx';
|
|
15
15
|
import { dateFilterFn } from './filters/DateFilter.jsx';
|
|
16
16
|
import { booleanFilterFn } from './filters/BooleanFilter.jsx';
|
|
17
|
+
import renderers from './renderers/index.js';
|
|
17
18
|
|
|
18
19
|
var filterFnMap = {
|
|
19
20
|
[TYPES.STRING]: stringFilterFn,
|
|
@@ -24,12 +25,27 @@ var filterFnMap = {
|
|
|
24
25
|
|
|
25
26
|
var columnHelper = createColumnHelper();
|
|
26
27
|
|
|
28
|
+
// A column def may itself be a GROUP — `{ header, columns: [...] }` instead of
|
|
29
|
+
// `{ accessor, ... }` — which becomes a spanning header cell over its
|
|
30
|
+
// children (a pivoted date over the measures under it), same as Excel merges
|
|
31
|
+
// a date across the columns it covers. Optional and recursive: a caller that
|
|
32
|
+
// never nests columns gets exactly the flat header it always got.
|
|
33
|
+
function flattenLeaves(cols) {
|
|
34
|
+
var out = [];
|
|
35
|
+
for (var i = 0; i < cols.length; i++) {
|
|
36
|
+
var col = cols[i];
|
|
37
|
+
if (col.columns && col.columns.length) out = out.concat(flattenLeaves(col.columns));
|
|
38
|
+
else out.push(col);
|
|
39
|
+
}
|
|
40
|
+
return out;
|
|
41
|
+
}
|
|
42
|
+
|
|
27
43
|
/**
|
|
28
44
|
* Hook that wires TanStack Table with auto-detected column types and smart filters.
|
|
29
45
|
*
|
|
30
46
|
* @param {object} options
|
|
31
47
|
* @param {Array<object>} options.data - Row array
|
|
32
|
-
* @param {Array<object>} options.columns - [{ accessor, header, dataType?, cell? }]
|
|
48
|
+
* @param {Array<object>} options.columns - [{ accessor, header, dataType?, cell? } | { header, columns: [...] }]
|
|
33
49
|
* @param {number} [options.minDetectionRows] - Min samples for confident detection (default: 10)
|
|
34
50
|
* @param {number} [options.pageSize] - Rows per page (default: 20)
|
|
35
51
|
* @param {boolean} [options.enableSorting] - Default: true
|
|
@@ -64,14 +80,28 @@ export default function useTableController(options) {
|
|
|
64
80
|
}
|
|
65
81
|
|
|
66
82
|
// Run detection
|
|
67
|
-
|
|
83
|
+
// Leaves only — a group column has no accessor and no data of its own to
|
|
84
|
+
// sample, it is purely a spanning header over the columns that do.
|
|
85
|
+
var result = detectTypes(data, flattenLeaves(columns), minDetectionRows);
|
|
68
86
|
detectionRef.current = { types: result.types, confident: result.confident, dataRef: data };
|
|
69
87
|
return result.types;
|
|
70
88
|
}, [data, columns, minDetectionRows]);
|
|
71
89
|
|
|
72
90
|
// ── Build TanStack column defs ──
|
|
73
91
|
var tanstackColumns = useMemo(function() {
|
|
74
|
-
|
|
92
|
+
function build(col) {
|
|
93
|
+
// A group has no data of its own — column.group() renders it as a
|
|
94
|
+
// spanning header cell (TanStack's own colSpan) over whichever leaf
|
|
95
|
+
// columns are nested under it, and nothing else about those leaves
|
|
96
|
+
// changes: same filters, same sort, same cells they'd have flat.
|
|
97
|
+
if (col.columns && col.columns.length) {
|
|
98
|
+
return columnHelper.group({
|
|
99
|
+
id: col.id || col.header,
|
|
100
|
+
header: col.header,
|
|
101
|
+
columns: col.columns.map(build)
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
75
105
|
var type = detectedTypes.get(col.accessor) || TYPES.STRING;
|
|
76
106
|
var filterFn = filterFnMap[type] || stringFilterFn;
|
|
77
107
|
|
|
@@ -82,13 +112,46 @@ export default function useTableController(options) {
|
|
|
82
112
|
enableSorting: col.enableSorting !== false,
|
|
83
113
|
enableColumnFilter: col.enableColumnFilter !== false
|
|
84
114
|
};
|
|
85
|
-
if (col.cell)
|
|
115
|
+
if (col.cell) {
|
|
116
|
+
colDef.cell = col.cell;
|
|
117
|
+
} else if (col.render) {
|
|
118
|
+
var rendererName = typeof col.render === 'string' ? col.render : col.render.type;
|
|
119
|
+
var rendererFn = renderers[rendererName];
|
|
120
|
+
if (!rendererFn) {
|
|
121
|
+
throw new Error('[xeplr-ui-table] Unknown renderer "' + rendererName + '". Available: ' + Object.keys(renderers).join(', '));
|
|
122
|
+
}
|
|
123
|
+
var rendererConfig = typeof col.render === 'string' ? {} : col.render;
|
|
124
|
+
colDef.cell = rendererFn(rendererConfig);
|
|
125
|
+
}
|
|
86
126
|
return columnHelper.accessor(col.accessor, colDef);
|
|
87
|
-
}
|
|
127
|
+
}
|
|
128
|
+
return columns.map(build);
|
|
88
129
|
}, [columns, detectedTypes]);
|
|
89
130
|
|
|
90
131
|
// ── Table state ──
|
|
91
|
-
|
|
132
|
+
//
|
|
133
|
+
// Sorting can be CONTROLLED by the host. Uncontrolled is the default and is
|
|
134
|
+
// what a plain data grid wants: click a header, the table reorders itself.
|
|
135
|
+
//
|
|
136
|
+
// A host takes it over when the ordering is not the table's to decide.
|
|
137
|
+
// A grouped report is the case that forces it — its rows carry subtotals
|
|
138
|
+
// that must stay with their group, and columns whose values are derived
|
|
139
|
+
// from the row above them. Re-sorting such a result in the view layer
|
|
140
|
+
// scatters the subtotals and leaves every running total describing an order
|
|
141
|
+
// that is no longer on screen. So the host supplies the order and takes the
|
|
142
|
+
// header click as an instruction, which is what `manualSorting` means to
|
|
143
|
+
// TanStack: "already sorted, do not sort it again".
|
|
144
|
+
var controlledSorting = options.sorting !== undefined;
|
|
145
|
+
var [ownSorting, setOwnSorting] = useState([]);
|
|
146
|
+
var sorting = controlledSorting ? options.sorting : ownSorting;
|
|
147
|
+
var setSorting = function (updater) {
|
|
148
|
+
var next = typeof updater === 'function' ? updater(sorting) : updater;
|
|
149
|
+
if (controlledSorting) {
|
|
150
|
+
if (options.onSortingChange) options.onSortingChange(next);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
setOwnSorting(next);
|
|
154
|
+
};
|
|
92
155
|
var [columnFilters, setColumnFilters] = useState([]);
|
|
93
156
|
var [pagination, setPagination] = useState({ pageIndex: 0, pageSize: pageSize });
|
|
94
157
|
|
|
@@ -106,7 +169,11 @@ export default function useTableController(options) {
|
|
|
106
169
|
onPaginationChange: setPagination,
|
|
107
170
|
getCoreRowModel: getCoreRowModel(),
|
|
108
171
|
getFilteredRowModel: enableFiltering ? getFilteredRowModel() : undefined,
|
|
109
|
-
|
|
172
|
+
// Not applied when the host controls the order — the rows arrive sorted
|
|
173
|
+
// and sorting them again is both wasted work and, for a grouped result,
|
|
174
|
+
// wrong.
|
|
175
|
+
getSortedRowModel: (enableSorting && !controlledSorting) ? getSortedRowModel() : undefined,
|
|
176
|
+
manualSorting: controlledSorting,
|
|
110
177
|
getPaginationRowModel: enablePagination ? getPaginationRowModel() : undefined,
|
|
111
178
|
getFacetedRowModel: getFacetedRowModel(),
|
|
112
179
|
getFacetedUniqueValues: getFacetedUniqueValues(),
|