@cerberus-design/data-grid 0.25.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/LICENSE +201 -0
- package/README.md +35 -0
- package/dist/column-helpers.cjs +24 -0
- package/dist/column-helpers.d.cts +45 -0
- package/dist/column-helpers.d.ts +45 -0
- package/dist/column-helpers.js +20 -0
- package/dist/components/cerby-data-grid.client.cjs +14 -0
- package/dist/components/cerby-data-grid.client.d.cts +6 -0
- package/dist/components/cerby-data-grid.client.d.ts +6 -0
- package/dist/components/cerby-data-grid.client.js +10 -0
- package/dist/components/count-menu.client.cjs +52 -0
- package/dist/components/count-menu.client.d.cts +6 -0
- package/dist/components/count-menu.client.d.ts +6 -0
- package/dist/components/count-menu.client.js +48 -0
- package/dist/components/data-grid.client.cjs +85 -0
- package/dist/components/data-grid.client.d.cts +4 -0
- package/dist/components/data-grid.client.d.ts +4 -0
- package/dist/components/data-grid.client.js +81 -0
- package/dist/components/features.client.cjs +79 -0
- package/dist/components/features.client.d.cts +2 -0
- package/dist/components/features.client.d.ts +2 -0
- package/dist/components/features.client.js +75 -0
- package/dist/components/grid.client.cjs +319 -0
- package/dist/components/grid.client.d.cts +19 -0
- package/dist/components/grid.client.d.ts +19 -0
- package/dist/components/grid.client.js +312 -0
- package/dist/components/pagination.client.cjs +116 -0
- package/dist/components/pagination.client.d.cts +1 -0
- package/dist/components/pagination.client.d.ts +1 -0
- package/dist/components/pagination.client.js +112 -0
- package/dist/components/pinned-items.client.cjs +70 -0
- package/dist/components/pinned-items.client.d.cts +5 -0
- package/dist/components/pinned-items.client.d.ts +5 -0
- package/dist/components/pinned-items.client.js +66 -0
- package/dist/components/sort-items.client.cjs +58 -0
- package/dist/components/sort-items.client.d.cts +4 -0
- package/dist/components/sort-items.client.d.ts +4 -0
- package/dist/components/sort-items.client.js +54 -0
- package/dist/const.cjs +49 -0
- package/dist/const.d.cts +28 -0
- package/dist/const.d.ts +28 -0
- package/dist/const.js +33 -0
- package/dist/context.client.cjs +18 -0
- package/dist/context.client.d.cts +7 -0
- package/dist/context.client.d.ts +7 -0
- package/dist/context.client.js +13 -0
- package/dist/hooks.client.cjs +29 -0
- package/dist/hooks.client.d.cts +7 -0
- package/dist/hooks.client.d.ts +7 -0
- package/dist/hooks.client.js +23 -0
- package/dist/index.cjs +15 -0
- package/dist/index.d.cts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +4 -0
- package/dist/store.cjs +287 -0
- package/dist/store.d.cts +6 -0
- package/dist/store.d.ts +6 -0
- package/dist/store.js +283 -0
- package/dist/types.d.cts +198 -0
- package/dist/types.d.ts +198 -0
- package/dist/utils.cjs +59 -0
- package/dist/utils.d.cts +6 -0
- package/dist/utils.d.ts +6 -0
- package/dist/utils.js +51 -0
- package/dist/virtualizer.client.cjs +56 -0
- package/dist/virtualizer.client.d.cts +11 -0
- package/dist/virtualizer.client.d.ts +11 -0
- package/dist/virtualizer.client.js +52 -0
- package/package.json +72 -0
package/dist/store.cjs
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
5
|
+
|
|
6
|
+
const signals = require('@cerberus-design/signals');
|
|
7
|
+
const utils = require('./utils.cjs');
|
|
8
|
+
const _const = require('./const.cjs');
|
|
9
|
+
|
|
10
|
+
function createGridStore(options) {
|
|
11
|
+
const [containerWidth, setContainerWidth] = signals.createSignal(0);
|
|
12
|
+
const [rows, setRows] = signals.createSignal(options.data);
|
|
13
|
+
const [rowSize] = signals.createSignal(utils.determineRowHeight(options.rowSize));
|
|
14
|
+
const [globalFilter, setGlobalFilter] = signals.createSignal("");
|
|
15
|
+
const [sorting, setSorting] = signals.createSignal([]);
|
|
16
|
+
const [pageIndex, setPageIndex] = signals.createSignal(
|
|
17
|
+
utils.determinePageIndex(options.initialState?.pagination)
|
|
18
|
+
);
|
|
19
|
+
const [pageSize, setPageSize] = signals.createSignal(
|
|
20
|
+
utils.determinePageSize(options.initialState?.pagination)
|
|
21
|
+
);
|
|
22
|
+
const [pageRange] = signals.createSignal(
|
|
23
|
+
utils.determinePageRange(options.initialState?.pagination)
|
|
24
|
+
);
|
|
25
|
+
const [isServerPaginated] = signals.createSignal(
|
|
26
|
+
Boolean(utils.determineInitialCount(options.initialState?.pagination))
|
|
27
|
+
);
|
|
28
|
+
const initialCols = options.columns.map((col) => {
|
|
29
|
+
const pinnable = Boolean(col.features?.pinning);
|
|
30
|
+
const filterable = Boolean(col.features?.filter);
|
|
31
|
+
const sortable = Boolean(col.features?.sort);
|
|
32
|
+
const hasFeatures = pinnable || filterable || sortable;
|
|
33
|
+
const minWForFeatures = 100;
|
|
34
|
+
let finalWidth = col.width ?? 150;
|
|
35
|
+
if (hasFeatures && col.width && col.width < minWForFeatures) {
|
|
36
|
+
finalWidth = minWForFeatures;
|
|
37
|
+
}
|
|
38
|
+
const [isVisible] = signals.createSignal(true);
|
|
39
|
+
const [isFlex, setFlex] = signals.createSignal(col.width === void 0);
|
|
40
|
+
const [pinned, setPinned] = signals.createSignal(
|
|
41
|
+
col.features?.pinning?.defaultPosition ?? false
|
|
42
|
+
);
|
|
43
|
+
const [width, setColWidth] = signals.createSignal(finalWidth);
|
|
44
|
+
return {
|
|
45
|
+
id: col.id,
|
|
46
|
+
isFlex,
|
|
47
|
+
isVisible,
|
|
48
|
+
original: col,
|
|
49
|
+
pinned,
|
|
50
|
+
width,
|
|
51
|
+
getValue: col.accessor,
|
|
52
|
+
// feature flags
|
|
53
|
+
pinnable,
|
|
54
|
+
filterable,
|
|
55
|
+
sortable,
|
|
56
|
+
// setters
|
|
57
|
+
setFlex,
|
|
58
|
+
setPinned,
|
|
59
|
+
setColWidth
|
|
60
|
+
};
|
|
61
|
+
});
|
|
62
|
+
const [columns] = signals.createSignal(initialCols);
|
|
63
|
+
const currentPageRange = signals.createComputed(
|
|
64
|
+
() => {
|
|
65
|
+
const dataIdx = pageIndex() - 1;
|
|
66
|
+
const isFirstPage = dataIdx === 0;
|
|
67
|
+
const start = isFirstPage ? 0 : dataIdx * pageSize() - 1;
|
|
68
|
+
return {
|
|
69
|
+
start,
|
|
70
|
+
end: pageIndex() * pageSize()
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
const processedRows = signals.createComputed(() => {
|
|
75
|
+
let result = [...rows()];
|
|
76
|
+
const filter = globalFilter().toLowerCase();
|
|
77
|
+
const sortState = sorting();
|
|
78
|
+
if (filter) {
|
|
79
|
+
result = result.filter((row) => {
|
|
80
|
+
return columns().some((col) => {
|
|
81
|
+
if (!col.filterable) return false;
|
|
82
|
+
const val = String(col.getValue(row)).toLowerCase();
|
|
83
|
+
return val.includes(filter);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
if (sortState.length > 0) {
|
|
88
|
+
result.sort((a, b) => {
|
|
89
|
+
for (const sort of sortState) {
|
|
90
|
+
const col = columns().find((c) => c.id === sort.id);
|
|
91
|
+
if (!col) continue;
|
|
92
|
+
const valA = col.getValue(a);
|
|
93
|
+
const valB = col.getValue(b);
|
|
94
|
+
if (valA === valB) continue;
|
|
95
|
+
let comparison = 0;
|
|
96
|
+
const customComparator = typeof col.original.features?.sort === "object" ? col.original.features.sort.comparator : void 0;
|
|
97
|
+
if (customComparator) {
|
|
98
|
+
comparison = customComparator(valA, valB);
|
|
99
|
+
} else {
|
|
100
|
+
comparison = valA > valB ? 1 : -1;
|
|
101
|
+
}
|
|
102
|
+
return sort.desc ? -comparison : comparison;
|
|
103
|
+
}
|
|
104
|
+
return 0;
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return result;
|
|
108
|
+
});
|
|
109
|
+
const rowCount = signals.createComputed(
|
|
110
|
+
() => utils.determineInitialCount(options?.initialState?.pagination) ?? processedRows().length
|
|
111
|
+
);
|
|
112
|
+
const pageCount = signals.createComputed(() => Math.ceil(rowCount() / pageSize()));
|
|
113
|
+
const orderedColumns = signals.createComputed(() => {
|
|
114
|
+
const left = [];
|
|
115
|
+
const center = [];
|
|
116
|
+
const right = [];
|
|
117
|
+
columns().forEach((col) => {
|
|
118
|
+
const pin = col.pinned();
|
|
119
|
+
if (pin === "left") left.push(col);
|
|
120
|
+
else if (pin === "right") right.push(col);
|
|
121
|
+
else center.push(col);
|
|
122
|
+
});
|
|
123
|
+
return [...left, ...center, ...right];
|
|
124
|
+
});
|
|
125
|
+
const visibleRows = signals.createComputed(() => {
|
|
126
|
+
if (pageSize() && pageCount() > 1) {
|
|
127
|
+
const currentRange = currentPageRange();
|
|
128
|
+
return processedRows().slice(currentRange.start, currentRange.end);
|
|
129
|
+
}
|
|
130
|
+
return processedRows();
|
|
131
|
+
});
|
|
132
|
+
const rootCssVars = signals.createComputed(() => {
|
|
133
|
+
const vars = {};
|
|
134
|
+
const visibleCols = [];
|
|
135
|
+
const cols = columns();
|
|
136
|
+
const cWidth = containerWidth();
|
|
137
|
+
let fixedSpace = 0;
|
|
138
|
+
let flexCount = 0;
|
|
139
|
+
for (let i = 0; i < cols.length; i++) {
|
|
140
|
+
const col = cols[i];
|
|
141
|
+
if (!col.isVisible()) continue;
|
|
142
|
+
visibleCols.push(col);
|
|
143
|
+
if (col.isFlex()) {
|
|
144
|
+
flexCount++;
|
|
145
|
+
} else {
|
|
146
|
+
fixedSpace += col.width();
|
|
147
|
+
}
|
|
148
|
+
const order = orderedColumns().findIndex(
|
|
149
|
+
(orderedCol) => orderedCol.id === col.id
|
|
150
|
+
);
|
|
151
|
+
vars[`--col-${col.id}-order`] = `${order}`;
|
|
152
|
+
}
|
|
153
|
+
const remainingSpace = Math.max(0, cWidth - fixedSpace);
|
|
154
|
+
const flexWidth = flexCount > 0 ? remainingSpace / flexCount : 0;
|
|
155
|
+
let leftOffset = 0;
|
|
156
|
+
let totalW = 0;
|
|
157
|
+
const computedWidths = new Float64Array(visibleCols.length);
|
|
158
|
+
for (let i = 0; i < visibleCols.length; i++) {
|
|
159
|
+
const col = visibleCols[i];
|
|
160
|
+
let finalWidth = col.width();
|
|
161
|
+
if (col.isFlex()) {
|
|
162
|
+
finalWidth = Math.max(col.original.minWidth ?? 150, flexWidth);
|
|
163
|
+
}
|
|
164
|
+
computedWidths[i] = finalWidth;
|
|
165
|
+
totalW += finalWidth;
|
|
166
|
+
vars[`--col-${col.id}-width`] = `${finalWidth}px`;
|
|
167
|
+
if (col.pinned() === "left") {
|
|
168
|
+
vars[`--col-${col.id}-left`] = `${leftOffset}px`;
|
|
169
|
+
leftOffset += finalWidth;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
let rightOffset = 0;
|
|
173
|
+
for (let i = visibleCols.length - 1; i >= 0; i--) {
|
|
174
|
+
const col = visibleCols[i];
|
|
175
|
+
if (col.pinned() === "right") {
|
|
176
|
+
vars[`--col-${col.id}-right`] = `${rightOffset}px`;
|
|
177
|
+
rightOffset += computedWidths[i];
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
vars["--total-grid-width"] = `${totalW}px`;
|
|
181
|
+
vars["--row-height"] = `${rowSize()}px`;
|
|
182
|
+
return vars;
|
|
183
|
+
});
|
|
184
|
+
const totalWidth = signals.createComputed(
|
|
185
|
+
() => columns().reduce((acc, c) => acc + c.width(), 0)
|
|
186
|
+
);
|
|
187
|
+
return {
|
|
188
|
+
columns,
|
|
189
|
+
rows,
|
|
190
|
+
globalFilter,
|
|
191
|
+
sorting,
|
|
192
|
+
pageCount,
|
|
193
|
+
pageIndex,
|
|
194
|
+
pageSize,
|
|
195
|
+
pageRange,
|
|
196
|
+
currentPageRange,
|
|
197
|
+
isServerPaginated,
|
|
198
|
+
rootCssVars,
|
|
199
|
+
rowCount,
|
|
200
|
+
rowSize,
|
|
201
|
+
totalWidth,
|
|
202
|
+
visibleRows,
|
|
203
|
+
// Actions
|
|
204
|
+
updateData: (newData) => {
|
|
205
|
+
setRows(newData);
|
|
206
|
+
},
|
|
207
|
+
setSort: (colId, direction, multi = false) => {
|
|
208
|
+
if (direction === null) {
|
|
209
|
+
setSorting(sorting().filter((s) => s.id !== colId));
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
const current = sorting();
|
|
213
|
+
const newSort = { id: colId, desc: direction === "desc" };
|
|
214
|
+
if (multi) {
|
|
215
|
+
const existingIndex = current.findIndex((s) => s.id === colId);
|
|
216
|
+
if (existingIndex >= 0) {
|
|
217
|
+
const next = [...current];
|
|
218
|
+
next[existingIndex] = newSort;
|
|
219
|
+
setSorting(next);
|
|
220
|
+
} else {
|
|
221
|
+
setSorting([...current, newSort]);
|
|
222
|
+
}
|
|
223
|
+
} else {
|
|
224
|
+
setSorting([newSort]);
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
togglePinned: (colId, state) => {
|
|
228
|
+
const col = columns().find((c) => c.id === colId);
|
|
229
|
+
if (col) col.setPinned(state ?? false);
|
|
230
|
+
},
|
|
231
|
+
toggleSort: (colId, multi) => {
|
|
232
|
+
const current = sorting();
|
|
233
|
+
const exists = current.findIndex((s) => s.id === colId) !== -1;
|
|
234
|
+
const updatedSort = current.map((s) => {
|
|
235
|
+
if (s.id === colId) {
|
|
236
|
+
return { ...s, desc: !s.desc };
|
|
237
|
+
}
|
|
238
|
+
return s;
|
|
239
|
+
});
|
|
240
|
+
if (exists) {
|
|
241
|
+
setSorting(multi ? [...current, ...updatedSort] : [...updatedSort]);
|
|
242
|
+
} else {
|
|
243
|
+
const newSort = { id: colId, desc: true };
|
|
244
|
+
setSorting(multi ? [...current, newSort] : [newSort]);
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
setPage: (details) => {
|
|
248
|
+
setPageIndex(details.page);
|
|
249
|
+
options.onPageChange?.(details);
|
|
250
|
+
},
|
|
251
|
+
setPageSize: (size) => {
|
|
252
|
+
if (isServerPaginated()) {
|
|
253
|
+
setPageIndex(_const.DEFAULT_PAGE_IDX);
|
|
254
|
+
}
|
|
255
|
+
setPageSize(size);
|
|
256
|
+
},
|
|
257
|
+
setGlobalFilter: (val) => {
|
|
258
|
+
signals.batch(() => {
|
|
259
|
+
setGlobalFilter(val);
|
|
260
|
+
setPageIndex(_const.DEFAULT_PAGE_IDX);
|
|
261
|
+
});
|
|
262
|
+
},
|
|
263
|
+
setContainerWidth: (w) => {
|
|
264
|
+
setContainerWidth(w);
|
|
265
|
+
},
|
|
266
|
+
resizeColumn: (colId, delta) => {
|
|
267
|
+
const col = columns().find((c) => c.id === colId);
|
|
268
|
+
if (col) {
|
|
269
|
+
if (col.isFlex()) {
|
|
270
|
+
const fixedSpace = columns().filter((c) => !c.isFlex()).reduce((a, b) => a + b.width(), 0);
|
|
271
|
+
const flexCount = columns().filter((c) => c.isFlex()).length;
|
|
272
|
+
const currentFlexWidth = Math.max(
|
|
273
|
+
col.original.minWidth ?? 150,
|
|
274
|
+
(containerWidth() - fixedSpace) / flexCount
|
|
275
|
+
);
|
|
276
|
+
col.setColWidth(currentFlexWidth);
|
|
277
|
+
col.setFlex(false);
|
|
278
|
+
}
|
|
279
|
+
col.setColWidth(
|
|
280
|
+
Math.max(col.original.minWidth ?? 50, col.width() + delta)
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
exports.createGridStore = createGridStore;
|
package/dist/store.d.cts
ADDED
package/dist/store.d.ts
ADDED
package/dist/store.js
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { createSignal, createComputed, batch } from '@cerberus-design/signals';
|
|
3
|
+
import { determineRowHeight, determinePageIndex, determinePageSize, determinePageRange, determineInitialCount } from './utils.js';
|
|
4
|
+
import { DEFAULT_PAGE_IDX } from './const.js';
|
|
5
|
+
|
|
6
|
+
function createGridStore(options) {
|
|
7
|
+
const [containerWidth, setContainerWidth] = createSignal(0);
|
|
8
|
+
const [rows, setRows] = createSignal(options.data);
|
|
9
|
+
const [rowSize] = createSignal(determineRowHeight(options.rowSize));
|
|
10
|
+
const [globalFilter, setGlobalFilter] = createSignal("");
|
|
11
|
+
const [sorting, setSorting] = createSignal([]);
|
|
12
|
+
const [pageIndex, setPageIndex] = createSignal(
|
|
13
|
+
determinePageIndex(options.initialState?.pagination)
|
|
14
|
+
);
|
|
15
|
+
const [pageSize, setPageSize] = createSignal(
|
|
16
|
+
determinePageSize(options.initialState?.pagination)
|
|
17
|
+
);
|
|
18
|
+
const [pageRange] = createSignal(
|
|
19
|
+
determinePageRange(options.initialState?.pagination)
|
|
20
|
+
);
|
|
21
|
+
const [isServerPaginated] = createSignal(
|
|
22
|
+
Boolean(determineInitialCount(options.initialState?.pagination))
|
|
23
|
+
);
|
|
24
|
+
const initialCols = options.columns.map((col) => {
|
|
25
|
+
const pinnable = Boolean(col.features?.pinning);
|
|
26
|
+
const filterable = Boolean(col.features?.filter);
|
|
27
|
+
const sortable = Boolean(col.features?.sort);
|
|
28
|
+
const hasFeatures = pinnable || filterable || sortable;
|
|
29
|
+
const minWForFeatures = 100;
|
|
30
|
+
let finalWidth = col.width ?? 150;
|
|
31
|
+
if (hasFeatures && col.width && col.width < minWForFeatures) {
|
|
32
|
+
finalWidth = minWForFeatures;
|
|
33
|
+
}
|
|
34
|
+
const [isVisible] = createSignal(true);
|
|
35
|
+
const [isFlex, setFlex] = createSignal(col.width === void 0);
|
|
36
|
+
const [pinned, setPinned] = createSignal(
|
|
37
|
+
col.features?.pinning?.defaultPosition ?? false
|
|
38
|
+
);
|
|
39
|
+
const [width, setColWidth] = createSignal(finalWidth);
|
|
40
|
+
return {
|
|
41
|
+
id: col.id,
|
|
42
|
+
isFlex,
|
|
43
|
+
isVisible,
|
|
44
|
+
original: col,
|
|
45
|
+
pinned,
|
|
46
|
+
width,
|
|
47
|
+
getValue: col.accessor,
|
|
48
|
+
// feature flags
|
|
49
|
+
pinnable,
|
|
50
|
+
filterable,
|
|
51
|
+
sortable,
|
|
52
|
+
// setters
|
|
53
|
+
setFlex,
|
|
54
|
+
setPinned,
|
|
55
|
+
setColWidth
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
const [columns] = createSignal(initialCols);
|
|
59
|
+
const currentPageRange = createComputed(
|
|
60
|
+
() => {
|
|
61
|
+
const dataIdx = pageIndex() - 1;
|
|
62
|
+
const isFirstPage = dataIdx === 0;
|
|
63
|
+
const start = isFirstPage ? 0 : dataIdx * pageSize() - 1;
|
|
64
|
+
return {
|
|
65
|
+
start,
|
|
66
|
+
end: pageIndex() * pageSize()
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
const processedRows = createComputed(() => {
|
|
71
|
+
let result = [...rows()];
|
|
72
|
+
const filter = globalFilter().toLowerCase();
|
|
73
|
+
const sortState = sorting();
|
|
74
|
+
if (filter) {
|
|
75
|
+
result = result.filter((row) => {
|
|
76
|
+
return columns().some((col) => {
|
|
77
|
+
if (!col.filterable) return false;
|
|
78
|
+
const val = String(col.getValue(row)).toLowerCase();
|
|
79
|
+
return val.includes(filter);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
if (sortState.length > 0) {
|
|
84
|
+
result.sort((a, b) => {
|
|
85
|
+
for (const sort of sortState) {
|
|
86
|
+
const col = columns().find((c) => c.id === sort.id);
|
|
87
|
+
if (!col) continue;
|
|
88
|
+
const valA = col.getValue(a);
|
|
89
|
+
const valB = col.getValue(b);
|
|
90
|
+
if (valA === valB) continue;
|
|
91
|
+
let comparison = 0;
|
|
92
|
+
const customComparator = typeof col.original.features?.sort === "object" ? col.original.features.sort.comparator : void 0;
|
|
93
|
+
if (customComparator) {
|
|
94
|
+
comparison = customComparator(valA, valB);
|
|
95
|
+
} else {
|
|
96
|
+
comparison = valA > valB ? 1 : -1;
|
|
97
|
+
}
|
|
98
|
+
return sort.desc ? -comparison : comparison;
|
|
99
|
+
}
|
|
100
|
+
return 0;
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
return result;
|
|
104
|
+
});
|
|
105
|
+
const rowCount = createComputed(
|
|
106
|
+
() => determineInitialCount(options?.initialState?.pagination) ?? processedRows().length
|
|
107
|
+
);
|
|
108
|
+
const pageCount = createComputed(() => Math.ceil(rowCount() / pageSize()));
|
|
109
|
+
const orderedColumns = createComputed(() => {
|
|
110
|
+
const left = [];
|
|
111
|
+
const center = [];
|
|
112
|
+
const right = [];
|
|
113
|
+
columns().forEach((col) => {
|
|
114
|
+
const pin = col.pinned();
|
|
115
|
+
if (pin === "left") left.push(col);
|
|
116
|
+
else if (pin === "right") right.push(col);
|
|
117
|
+
else center.push(col);
|
|
118
|
+
});
|
|
119
|
+
return [...left, ...center, ...right];
|
|
120
|
+
});
|
|
121
|
+
const visibleRows = createComputed(() => {
|
|
122
|
+
if (pageSize() && pageCount() > 1) {
|
|
123
|
+
const currentRange = currentPageRange();
|
|
124
|
+
return processedRows().slice(currentRange.start, currentRange.end);
|
|
125
|
+
}
|
|
126
|
+
return processedRows();
|
|
127
|
+
});
|
|
128
|
+
const rootCssVars = createComputed(() => {
|
|
129
|
+
const vars = {};
|
|
130
|
+
const visibleCols = [];
|
|
131
|
+
const cols = columns();
|
|
132
|
+
const cWidth = containerWidth();
|
|
133
|
+
let fixedSpace = 0;
|
|
134
|
+
let flexCount = 0;
|
|
135
|
+
for (let i = 0; i < cols.length; i++) {
|
|
136
|
+
const col = cols[i];
|
|
137
|
+
if (!col.isVisible()) continue;
|
|
138
|
+
visibleCols.push(col);
|
|
139
|
+
if (col.isFlex()) {
|
|
140
|
+
flexCount++;
|
|
141
|
+
} else {
|
|
142
|
+
fixedSpace += col.width();
|
|
143
|
+
}
|
|
144
|
+
const order = orderedColumns().findIndex(
|
|
145
|
+
(orderedCol) => orderedCol.id === col.id
|
|
146
|
+
);
|
|
147
|
+
vars[`--col-${col.id}-order`] = `${order}`;
|
|
148
|
+
}
|
|
149
|
+
const remainingSpace = Math.max(0, cWidth - fixedSpace);
|
|
150
|
+
const flexWidth = flexCount > 0 ? remainingSpace / flexCount : 0;
|
|
151
|
+
let leftOffset = 0;
|
|
152
|
+
let totalW = 0;
|
|
153
|
+
const computedWidths = new Float64Array(visibleCols.length);
|
|
154
|
+
for (let i = 0; i < visibleCols.length; i++) {
|
|
155
|
+
const col = visibleCols[i];
|
|
156
|
+
let finalWidth = col.width();
|
|
157
|
+
if (col.isFlex()) {
|
|
158
|
+
finalWidth = Math.max(col.original.minWidth ?? 150, flexWidth);
|
|
159
|
+
}
|
|
160
|
+
computedWidths[i] = finalWidth;
|
|
161
|
+
totalW += finalWidth;
|
|
162
|
+
vars[`--col-${col.id}-width`] = `${finalWidth}px`;
|
|
163
|
+
if (col.pinned() === "left") {
|
|
164
|
+
vars[`--col-${col.id}-left`] = `${leftOffset}px`;
|
|
165
|
+
leftOffset += finalWidth;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
let rightOffset = 0;
|
|
169
|
+
for (let i = visibleCols.length - 1; i >= 0; i--) {
|
|
170
|
+
const col = visibleCols[i];
|
|
171
|
+
if (col.pinned() === "right") {
|
|
172
|
+
vars[`--col-${col.id}-right`] = `${rightOffset}px`;
|
|
173
|
+
rightOffset += computedWidths[i];
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
vars["--total-grid-width"] = `${totalW}px`;
|
|
177
|
+
vars["--row-height"] = `${rowSize()}px`;
|
|
178
|
+
return vars;
|
|
179
|
+
});
|
|
180
|
+
const totalWidth = createComputed(
|
|
181
|
+
() => columns().reduce((acc, c) => acc + c.width(), 0)
|
|
182
|
+
);
|
|
183
|
+
return {
|
|
184
|
+
columns,
|
|
185
|
+
rows,
|
|
186
|
+
globalFilter,
|
|
187
|
+
sorting,
|
|
188
|
+
pageCount,
|
|
189
|
+
pageIndex,
|
|
190
|
+
pageSize,
|
|
191
|
+
pageRange,
|
|
192
|
+
currentPageRange,
|
|
193
|
+
isServerPaginated,
|
|
194
|
+
rootCssVars,
|
|
195
|
+
rowCount,
|
|
196
|
+
rowSize,
|
|
197
|
+
totalWidth,
|
|
198
|
+
visibleRows,
|
|
199
|
+
// Actions
|
|
200
|
+
updateData: (newData) => {
|
|
201
|
+
setRows(newData);
|
|
202
|
+
},
|
|
203
|
+
setSort: (colId, direction, multi = false) => {
|
|
204
|
+
if (direction === null) {
|
|
205
|
+
setSorting(sorting().filter((s) => s.id !== colId));
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
const current = sorting();
|
|
209
|
+
const newSort = { id: colId, desc: direction === "desc" };
|
|
210
|
+
if (multi) {
|
|
211
|
+
const existingIndex = current.findIndex((s) => s.id === colId);
|
|
212
|
+
if (existingIndex >= 0) {
|
|
213
|
+
const next = [...current];
|
|
214
|
+
next[existingIndex] = newSort;
|
|
215
|
+
setSorting(next);
|
|
216
|
+
} else {
|
|
217
|
+
setSorting([...current, newSort]);
|
|
218
|
+
}
|
|
219
|
+
} else {
|
|
220
|
+
setSorting([newSort]);
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
togglePinned: (colId, state) => {
|
|
224
|
+
const col = columns().find((c) => c.id === colId);
|
|
225
|
+
if (col) col.setPinned(state ?? false);
|
|
226
|
+
},
|
|
227
|
+
toggleSort: (colId, multi) => {
|
|
228
|
+
const current = sorting();
|
|
229
|
+
const exists = current.findIndex((s) => s.id === colId) !== -1;
|
|
230
|
+
const updatedSort = current.map((s) => {
|
|
231
|
+
if (s.id === colId) {
|
|
232
|
+
return { ...s, desc: !s.desc };
|
|
233
|
+
}
|
|
234
|
+
return s;
|
|
235
|
+
});
|
|
236
|
+
if (exists) {
|
|
237
|
+
setSorting(multi ? [...current, ...updatedSort] : [...updatedSort]);
|
|
238
|
+
} else {
|
|
239
|
+
const newSort = { id: colId, desc: true };
|
|
240
|
+
setSorting(multi ? [...current, newSort] : [newSort]);
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
setPage: (details) => {
|
|
244
|
+
setPageIndex(details.page);
|
|
245
|
+
options.onPageChange?.(details);
|
|
246
|
+
},
|
|
247
|
+
setPageSize: (size) => {
|
|
248
|
+
if (isServerPaginated()) {
|
|
249
|
+
setPageIndex(DEFAULT_PAGE_IDX);
|
|
250
|
+
}
|
|
251
|
+
setPageSize(size);
|
|
252
|
+
},
|
|
253
|
+
setGlobalFilter: (val) => {
|
|
254
|
+
batch(() => {
|
|
255
|
+
setGlobalFilter(val);
|
|
256
|
+
setPageIndex(DEFAULT_PAGE_IDX);
|
|
257
|
+
});
|
|
258
|
+
},
|
|
259
|
+
setContainerWidth: (w) => {
|
|
260
|
+
setContainerWidth(w);
|
|
261
|
+
},
|
|
262
|
+
resizeColumn: (colId, delta) => {
|
|
263
|
+
const col = columns().find((c) => c.id === colId);
|
|
264
|
+
if (col) {
|
|
265
|
+
if (col.isFlex()) {
|
|
266
|
+
const fixedSpace = columns().filter((c) => !c.isFlex()).reduce((a, b) => a + b.width(), 0);
|
|
267
|
+
const flexCount = columns().filter((c) => c.isFlex()).length;
|
|
268
|
+
const currentFlexWidth = Math.max(
|
|
269
|
+
col.original.minWidth ?? 150,
|
|
270
|
+
(containerWidth() - fixedSpace) / flexCount
|
|
271
|
+
);
|
|
272
|
+
col.setColWidth(currentFlexWidth);
|
|
273
|
+
col.setFlex(false);
|
|
274
|
+
}
|
|
275
|
+
col.setColWidth(
|
|
276
|
+
Math.max(col.original.minWidth ?? 50, col.width() + delta)
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
export { createGridStore };
|