@cerberus-design/data-grid 0.25.3 → 1.0.0-rc.5

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