@ornery/ui-grid-react 1.0.5 → 1.0.6
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/UiGrid.d.ts.map +1 -1
- package/dist/index.js +108 -3
- package/dist/index.mjs +108 -3
- package/dist/rustWasmGridEngine.d.ts +2 -3
- package/dist/rustWasmGridEngine.d.ts.map +1 -1
- package/dist/useGridState.d.ts +1 -1
- package/dist/useGridState.d.ts.map +1 -1
- package/package.json +5 -4
- package/src/UiGrid.test.tsx +49 -0
- package/src/UiGrid.tsx +119 -5
- package/src/rustWasmGridEngine.test.ts +9 -18
- package/src/rustWasmGridEngine.ts +2 -11
- package/src/useGridState.ts +11 -2
- package/tsconfig.json +1 -1
- package/vitest.config.ts +8 -1
package/dist/UiGrid.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UiGrid.d.ts","sourceRoot":"","sources":["../src/UiGrid.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"UiGrid.d.ts","sourceRoot":"","sources":["../src/UiGrid.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAEV,WAAW,EACX,uBAAuB,EAEvB,SAAS,EACV,MAAM,sBAAsB,CAAC;AAQ9B,MAAM,WAAW,mBAAmB;IAClC,CAAC,UAAU,EAAE,MAAM,GAAG,CAAC,OAAO,EAAE,uBAAuB,KAAK,KAAK,CAAC,SAAS,CAAC;CAC7E;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,WAAW,CAAC;IACrB,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,CAAC;IACzC,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAaD,wBAAgB,MAAM,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,SAAS,EAAE,EAAE,WAAW,2CAsSvF"}
|
package/dist/index.js
CHANGED
|
@@ -58,6 +58,33 @@ function UiGrid({ options, onRegisterApi, cellRenderers, className }) {
|
|
|
58
58
|
const optionsRef = import_react.default.useRef(options);
|
|
59
59
|
optionsRef.current = options;
|
|
60
60
|
const currentSlotColumnsRef = import_react.default.useRef([]);
|
|
61
|
+
const wrapperRenderVersionRef = import_react.default.useRef(0);
|
|
62
|
+
const scheduledWrapperRenderVersionRef = import_react.default.useRef(0);
|
|
63
|
+
const wrapperRenderWaitersRef = import_react.default.useRef([]);
|
|
64
|
+
const benchmarkSubscriptionUnsubscribeRef = import_react.default.useRef(null);
|
|
65
|
+
import_react.default.useLayoutEffect(() => {
|
|
66
|
+
wrapperRenderVersionRef.current += 1;
|
|
67
|
+
const ready = wrapperRenderWaitersRef.current.filter(
|
|
68
|
+
(waiter) => waiter.target <= wrapperRenderVersionRef.current
|
|
69
|
+
);
|
|
70
|
+
if (ready.length === 0) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
wrapperRenderWaitersRef.current = wrapperRenderWaitersRef.current.filter(
|
|
74
|
+
(waiter) => waiter.target > wrapperRenderVersionRef.current
|
|
75
|
+
);
|
|
76
|
+
for (const waiter of ready) {
|
|
77
|
+
waiter.resolve();
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
import_react.default.useEffect(() => {
|
|
81
|
+
return () => {
|
|
82
|
+
if (benchmarkSubscriptionUnsubscribeRef.current) {
|
|
83
|
+
benchmarkSubscriptionUnsubscribeRef.current();
|
|
84
|
+
benchmarkSubscriptionUnsubscribeRef.current = null;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}, []);
|
|
61
88
|
import_react.default.useEffect(() => {
|
|
62
89
|
const container = containerRef.current;
|
|
63
90
|
if (!container) return;
|
|
@@ -81,6 +108,10 @@ function UiGrid({ options, onRegisterApi, cellRenderers, className }) {
|
|
|
81
108
|
void mount();
|
|
82
109
|
return () => {
|
|
83
110
|
disposed = true;
|
|
111
|
+
if (benchmarkSubscriptionUnsubscribeRef.current) {
|
|
112
|
+
benchmarkSubscriptionUnsubscribeRef.current();
|
|
113
|
+
benchmarkSubscriptionUnsubscribeRef.current = null;
|
|
114
|
+
}
|
|
84
115
|
if (el) {
|
|
85
116
|
el.removeEventListener("cellSlotsChanged", handleCellSlotsChanged);
|
|
86
117
|
el.remove();
|
|
@@ -109,6 +140,7 @@ function UiGrid({ options, onRegisterApi, cellRenderers, className }) {
|
|
|
109
140
|
const col = options.columnDefs?.find((c) => c.name === entry.columnName);
|
|
110
141
|
const value = col?.field ? getNestedValue(row, col.field) : row[entry.columnName];
|
|
111
142
|
if (entry.context.value !== value || entry.context.row !== row) {
|
|
143
|
+
markWrapperRenderScheduled();
|
|
112
144
|
nextSlots.set(key, {
|
|
113
145
|
...entry,
|
|
114
146
|
context: { ...entry.context, $implicit: value, value, row }
|
|
@@ -118,6 +150,67 @@ function UiGrid({ options, onRegisterApi, cellRenderers, className }) {
|
|
|
118
150
|
}
|
|
119
151
|
if (changed) setSlots(nextSlots);
|
|
120
152
|
}, [options.data]);
|
|
153
|
+
function markWrapperRenderScheduled() {
|
|
154
|
+
scheduledWrapperRenderVersionRef.current = Math.max(
|
|
155
|
+
scheduledWrapperRenderVersionRef.current,
|
|
156
|
+
wrapperRenderVersionRef.current + 1
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
function waitForScheduledWrapperRender() {
|
|
160
|
+
const target = scheduledWrapperRenderVersionRef.current;
|
|
161
|
+
if (target <= wrapperRenderVersionRef.current) {
|
|
162
|
+
return Promise.resolve();
|
|
163
|
+
}
|
|
164
|
+
return new Promise((resolve) => {
|
|
165
|
+
wrapperRenderWaitersRef.current.push({ target, resolve });
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
function createWrappedGridApi(api, opts) {
|
|
169
|
+
const benchmarkListeners = /* @__PURE__ */ new Set();
|
|
170
|
+
const now = () => typeof performance === "undefined" ? Date.now() : performance.now();
|
|
171
|
+
if (benchmarkSubscriptionUnsubscribeRef.current) {
|
|
172
|
+
benchmarkSubscriptionUnsubscribeRef.current();
|
|
173
|
+
}
|
|
174
|
+
benchmarkSubscriptionUnsubscribeRef.current = api.core.on.benchmarkComplete((result) => {
|
|
175
|
+
for (const listener of benchmarkListeners) {
|
|
176
|
+
listener(result);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
return {
|
|
180
|
+
...api,
|
|
181
|
+
core: {
|
|
182
|
+
...api.core,
|
|
183
|
+
on: {
|
|
184
|
+
...api.core.on,
|
|
185
|
+
benchmarkComplete: (listener) => {
|
|
186
|
+
benchmarkListeners.add(listener);
|
|
187
|
+
return () => benchmarkListeners.delete(listener);
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
benchmark: async (iterations) => {
|
|
191
|
+
const loops = Math.max(1, iterations ?? opts.benchmark?.iterations ?? 25);
|
|
192
|
+
const started = now();
|
|
193
|
+
let lastResult = null;
|
|
194
|
+
for (let index = 0; index < loops; index += 1) {
|
|
195
|
+
lastResult = await api.core.benchmark(1);
|
|
196
|
+
await waitForScheduledWrapperRender();
|
|
197
|
+
}
|
|
198
|
+
const totalMs = now() - started;
|
|
199
|
+
const result = {
|
|
200
|
+
iterations: loops,
|
|
201
|
+
totalMs,
|
|
202
|
+
averageMs: totalMs / loops,
|
|
203
|
+
visibleRows: lastResult?.visibleRows ?? 0,
|
|
204
|
+
renderedItems: lastResult?.renderedItems ?? 0
|
|
205
|
+
};
|
|
206
|
+
for (const listener of benchmarkListeners) {
|
|
207
|
+
listener(result);
|
|
208
|
+
}
|
|
209
|
+
return result;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
}
|
|
121
214
|
function applyOptions(el, opts) {
|
|
122
215
|
const renderers2 = cellRenderersRef.current;
|
|
123
216
|
const cellSlotColumns = [];
|
|
@@ -131,8 +224,9 @@ function UiGrid({ options, onRegisterApi, cellRenderers, className }) {
|
|
|
131
224
|
const wrappedOptions = {
|
|
132
225
|
...opts,
|
|
133
226
|
onRegisterApi: (api) => {
|
|
134
|
-
|
|
135
|
-
|
|
227
|
+
const wrappedApi = createWrappedGridApi(api, opts);
|
|
228
|
+
onRegisterApiRef.current?.(wrappedApi);
|
|
229
|
+
opts.onRegisterApi?.(wrappedApi);
|
|
136
230
|
}
|
|
137
231
|
};
|
|
138
232
|
el.options = wrappedOptions;
|
|
@@ -147,6 +241,9 @@ function UiGrid({ options, onRegisterApi, cellRenderers, className }) {
|
|
|
147
241
|
const detail = event.detail;
|
|
148
242
|
const el = elementRef.current;
|
|
149
243
|
if (!el) return;
|
|
244
|
+
if (detail.removed.length > 0 || detail.added.length > 0) {
|
|
245
|
+
markWrapperRenderScheduled();
|
|
246
|
+
}
|
|
150
247
|
setSlots((prev) => {
|
|
151
248
|
const next = new Map(prev);
|
|
152
249
|
for (const slot of detail.removed) {
|
|
@@ -185,7 +282,15 @@ function UiGrid({ options, onRegisterApi, cellRenderers, className }) {
|
|
|
185
282
|
}
|
|
186
283
|
}
|
|
187
284
|
}
|
|
188
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
285
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
286
|
+
"div",
|
|
287
|
+
{
|
|
288
|
+
ref: containerRef,
|
|
289
|
+
className,
|
|
290
|
+
style: { display: "block", height: "100%", minHeight: 0 },
|
|
291
|
+
children: portals
|
|
292
|
+
}
|
|
293
|
+
);
|
|
189
294
|
}
|
|
190
295
|
function getNestedValue(obj, field) {
|
|
191
296
|
const parts = field.split(".");
|
package/dist/index.mjs
CHANGED
|
@@ -16,6 +16,33 @@ function UiGrid({ options, onRegisterApi, cellRenderers, className }) {
|
|
|
16
16
|
const optionsRef = React.useRef(options);
|
|
17
17
|
optionsRef.current = options;
|
|
18
18
|
const currentSlotColumnsRef = React.useRef([]);
|
|
19
|
+
const wrapperRenderVersionRef = React.useRef(0);
|
|
20
|
+
const scheduledWrapperRenderVersionRef = React.useRef(0);
|
|
21
|
+
const wrapperRenderWaitersRef = React.useRef([]);
|
|
22
|
+
const benchmarkSubscriptionUnsubscribeRef = React.useRef(null);
|
|
23
|
+
React.useLayoutEffect(() => {
|
|
24
|
+
wrapperRenderVersionRef.current += 1;
|
|
25
|
+
const ready = wrapperRenderWaitersRef.current.filter(
|
|
26
|
+
(waiter) => waiter.target <= wrapperRenderVersionRef.current
|
|
27
|
+
);
|
|
28
|
+
if (ready.length === 0) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
wrapperRenderWaitersRef.current = wrapperRenderWaitersRef.current.filter(
|
|
32
|
+
(waiter) => waiter.target > wrapperRenderVersionRef.current
|
|
33
|
+
);
|
|
34
|
+
for (const waiter of ready) {
|
|
35
|
+
waiter.resolve();
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
React.useEffect(() => {
|
|
39
|
+
return () => {
|
|
40
|
+
if (benchmarkSubscriptionUnsubscribeRef.current) {
|
|
41
|
+
benchmarkSubscriptionUnsubscribeRef.current();
|
|
42
|
+
benchmarkSubscriptionUnsubscribeRef.current = null;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}, []);
|
|
19
46
|
React.useEffect(() => {
|
|
20
47
|
const container = containerRef.current;
|
|
21
48
|
if (!container) return;
|
|
@@ -39,6 +66,10 @@ function UiGrid({ options, onRegisterApi, cellRenderers, className }) {
|
|
|
39
66
|
void mount();
|
|
40
67
|
return () => {
|
|
41
68
|
disposed = true;
|
|
69
|
+
if (benchmarkSubscriptionUnsubscribeRef.current) {
|
|
70
|
+
benchmarkSubscriptionUnsubscribeRef.current();
|
|
71
|
+
benchmarkSubscriptionUnsubscribeRef.current = null;
|
|
72
|
+
}
|
|
42
73
|
if (el) {
|
|
43
74
|
el.removeEventListener("cellSlotsChanged", handleCellSlotsChanged);
|
|
44
75
|
el.remove();
|
|
@@ -67,6 +98,7 @@ function UiGrid({ options, onRegisterApi, cellRenderers, className }) {
|
|
|
67
98
|
const col = options.columnDefs?.find((c) => c.name === entry.columnName);
|
|
68
99
|
const value = col?.field ? getNestedValue(row, col.field) : row[entry.columnName];
|
|
69
100
|
if (entry.context.value !== value || entry.context.row !== row) {
|
|
101
|
+
markWrapperRenderScheduled();
|
|
70
102
|
nextSlots.set(key, {
|
|
71
103
|
...entry,
|
|
72
104
|
context: { ...entry.context, $implicit: value, value, row }
|
|
@@ -76,6 +108,67 @@ function UiGrid({ options, onRegisterApi, cellRenderers, className }) {
|
|
|
76
108
|
}
|
|
77
109
|
if (changed) setSlots(nextSlots);
|
|
78
110
|
}, [options.data]);
|
|
111
|
+
function markWrapperRenderScheduled() {
|
|
112
|
+
scheduledWrapperRenderVersionRef.current = Math.max(
|
|
113
|
+
scheduledWrapperRenderVersionRef.current,
|
|
114
|
+
wrapperRenderVersionRef.current + 1
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
function waitForScheduledWrapperRender() {
|
|
118
|
+
const target = scheduledWrapperRenderVersionRef.current;
|
|
119
|
+
if (target <= wrapperRenderVersionRef.current) {
|
|
120
|
+
return Promise.resolve();
|
|
121
|
+
}
|
|
122
|
+
return new Promise((resolve) => {
|
|
123
|
+
wrapperRenderWaitersRef.current.push({ target, resolve });
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
function createWrappedGridApi(api, opts) {
|
|
127
|
+
const benchmarkListeners = /* @__PURE__ */ new Set();
|
|
128
|
+
const now = () => typeof performance === "undefined" ? Date.now() : performance.now();
|
|
129
|
+
if (benchmarkSubscriptionUnsubscribeRef.current) {
|
|
130
|
+
benchmarkSubscriptionUnsubscribeRef.current();
|
|
131
|
+
}
|
|
132
|
+
benchmarkSubscriptionUnsubscribeRef.current = api.core.on.benchmarkComplete((result) => {
|
|
133
|
+
for (const listener of benchmarkListeners) {
|
|
134
|
+
listener(result);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
return {
|
|
138
|
+
...api,
|
|
139
|
+
core: {
|
|
140
|
+
...api.core,
|
|
141
|
+
on: {
|
|
142
|
+
...api.core.on,
|
|
143
|
+
benchmarkComplete: (listener) => {
|
|
144
|
+
benchmarkListeners.add(listener);
|
|
145
|
+
return () => benchmarkListeners.delete(listener);
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
benchmark: async (iterations) => {
|
|
149
|
+
const loops = Math.max(1, iterations ?? opts.benchmark?.iterations ?? 25);
|
|
150
|
+
const started = now();
|
|
151
|
+
let lastResult = null;
|
|
152
|
+
for (let index = 0; index < loops; index += 1) {
|
|
153
|
+
lastResult = await api.core.benchmark(1);
|
|
154
|
+
await waitForScheduledWrapperRender();
|
|
155
|
+
}
|
|
156
|
+
const totalMs = now() - started;
|
|
157
|
+
const result = {
|
|
158
|
+
iterations: loops,
|
|
159
|
+
totalMs,
|
|
160
|
+
averageMs: totalMs / loops,
|
|
161
|
+
visibleRows: lastResult?.visibleRows ?? 0,
|
|
162
|
+
renderedItems: lastResult?.renderedItems ?? 0
|
|
163
|
+
};
|
|
164
|
+
for (const listener of benchmarkListeners) {
|
|
165
|
+
listener(result);
|
|
166
|
+
}
|
|
167
|
+
return result;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
}
|
|
79
172
|
function applyOptions(el, opts) {
|
|
80
173
|
const renderers2 = cellRenderersRef.current;
|
|
81
174
|
const cellSlotColumns = [];
|
|
@@ -89,8 +182,9 @@ function UiGrid({ options, onRegisterApi, cellRenderers, className }) {
|
|
|
89
182
|
const wrappedOptions = {
|
|
90
183
|
...opts,
|
|
91
184
|
onRegisterApi: (api) => {
|
|
92
|
-
|
|
93
|
-
|
|
185
|
+
const wrappedApi = createWrappedGridApi(api, opts);
|
|
186
|
+
onRegisterApiRef.current?.(wrappedApi);
|
|
187
|
+
opts.onRegisterApi?.(wrappedApi);
|
|
94
188
|
}
|
|
95
189
|
};
|
|
96
190
|
el.options = wrappedOptions;
|
|
@@ -105,6 +199,9 @@ function UiGrid({ options, onRegisterApi, cellRenderers, className }) {
|
|
|
105
199
|
const detail = event.detail;
|
|
106
200
|
const el = elementRef.current;
|
|
107
201
|
if (!el) return;
|
|
202
|
+
if (detail.removed.length > 0 || detail.added.length > 0) {
|
|
203
|
+
markWrapperRenderScheduled();
|
|
204
|
+
}
|
|
108
205
|
setSlots((prev) => {
|
|
109
206
|
const next = new Map(prev);
|
|
110
207
|
for (const slot of detail.removed) {
|
|
@@ -143,7 +240,15 @@ function UiGrid({ options, onRegisterApi, cellRenderers, className }) {
|
|
|
143
240
|
}
|
|
144
241
|
}
|
|
145
242
|
}
|
|
146
|
-
return /* @__PURE__ */ jsx(
|
|
243
|
+
return /* @__PURE__ */ jsx(
|
|
244
|
+
"div",
|
|
245
|
+
{
|
|
246
|
+
ref: containerRef,
|
|
247
|
+
className,
|
|
248
|
+
style: { display: "block", height: "100%", minHeight: 0 },
|
|
249
|
+
children: portals
|
|
250
|
+
}
|
|
251
|
+
);
|
|
147
252
|
}
|
|
148
253
|
function getNestedValue(obj, field) {
|
|
149
254
|
const parts = field.split(".");
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import type { PipelineResult } from '@ornery/ui-grid-core';
|
|
2
1
|
type UiGridWasmModule = {
|
|
3
|
-
|
|
2
|
+
default(input?: unknown): Promise<unknown>;
|
|
4
3
|
};
|
|
5
|
-
export declare function registerReactUiGridWasmEngineFromModule(
|
|
4
|
+
export declare function registerReactUiGridWasmEngineFromModule(_module: UiGridWasmModule): void;
|
|
6
5
|
export declare function enableReactUiGridWasmEngine(): Promise<void>;
|
|
7
6
|
export {};
|
|
8
7
|
//# sourceMappingURL=rustWasmGridEngine.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rustWasmGridEngine.d.ts","sourceRoot":"","sources":["../src/rustWasmGridEngine.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rustWasmGridEngine.d.ts","sourceRoot":"","sources":["../src/rustWasmGridEngine.ts"],"names":[],"mappings":"AAGA,KAAK,gBAAgB,GAAG;IACtB,OAAO,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC5C,CAAC;AAEF,wBAAgB,uCAAuC,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CACvF;AAED,wBAAsB,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC,CAGjE"}
|
package/dist/useGridState.d.ts
CHANGED
|
@@ -108,7 +108,7 @@ export interface UseGridStateResult {
|
|
|
108
108
|
nextPage: () => void;
|
|
109
109
|
previousPage: () => void;
|
|
110
110
|
onPageSizeChange: (value: string) => void;
|
|
111
|
-
runBenchmark: (iterations?: number) => GridBenchmarkResult
|
|
111
|
+
runBenchmark: (iterations?: number) => Promise<GridBenchmarkResult>;
|
|
112
112
|
exportCsv: () => void;
|
|
113
113
|
onViewportScroll: (startIndex: number) => void;
|
|
114
114
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useGridState.d.ts","sourceRoot":"","sources":["../src/useGridState.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"useGridState.d.ts","sourceRoot":"","sources":["../src/useGridState.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ornery/ui-grid-react",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "React wrapper for @ornery/ui-grid-core",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
"./styles": "./dist/ui-grid.css"
|
|
15
15
|
},
|
|
16
16
|
"peerDependencies": {
|
|
17
|
-
"@ornery/ui-grid-core": "1.0.
|
|
18
|
-
"@ornery/ui-grid-vanilla": "1.0.
|
|
17
|
+
"@ornery/ui-grid-core": "1.0.6",
|
|
18
|
+
"@ornery/ui-grid-vanilla": "1.0.6",
|
|
19
19
|
"react": "^18.0.0 || ^19.0.0",
|
|
20
20
|
"react-dom": "^18.0.0 || ^19.0.0"
|
|
21
21
|
},
|
|
@@ -36,8 +36,9 @@
|
|
|
36
36
|
},
|
|
37
37
|
"scripts": {
|
|
38
38
|
"start": "vite serve demo --config demo/vite.config.ts",
|
|
39
|
-
"build": "
|
|
39
|
+
"build": "tsup src/index.ts --format esm,cjs --tsconfig tsconfig.build.json --external react --external react-dom --external @ornery/ui-grid-core --external @ornery/ui-grid-vanilla && tsc -p tsconfig.dts.json && node -e \"require('fs').copyFileSync('src/ui-grid.css','dist/ui-grid.css')\"",
|
|
40
40
|
"test": "vitest run",
|
|
41
|
+
"test:coverage": "vitest run --coverage",
|
|
41
42
|
"test:watch": "vitest"
|
|
42
43
|
}
|
|
43
44
|
}
|
package/src/UiGrid.test.tsx
CHANGED
|
@@ -274,4 +274,53 @@ describe('UiGrid React component', () => {
|
|
|
274
274
|
|
|
275
275
|
expect(gridApi.core.getVisibleRows()).toHaveLength(3);
|
|
276
276
|
});
|
|
277
|
+
|
|
278
|
+
it('row selection + expandable rows: selection toggle only repaints the affected row', async () => {
|
|
279
|
+
// Regression test for the selection+expand performance issue. The patch
|
|
280
|
+
// path's per-row fingerprint cache (in the vanilla layer) skips cells
|
|
281
|
+
// whose visual state didn't change. The React wrapper inherits this fix
|
|
282
|
+
// automatically because it mounts the same vanilla element. This test
|
|
283
|
+
// pins the end-to-end behaviour: clicking the row-selection checkbox
|
|
284
|
+
// for one row must only flip ui-grid-row-selected on that row's cells —
|
|
285
|
+
// not invalidate any visible state on the unselected rows.
|
|
286
|
+
const expandableTemplate = { createEmbeddedView: () => undefined };
|
|
287
|
+
const { gridApi, shadowRoot } = await renderGrid({
|
|
288
|
+
enableRowSelection: true,
|
|
289
|
+
enableExpandable: true,
|
|
290
|
+
expandableRowTemplate:
|
|
291
|
+
expandableTemplate as unknown as GridOptions['expandableRowTemplate'],
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
const cellFor = (rowId: string, column: string): HTMLElement => {
|
|
295
|
+
const el = shadowRoot.querySelector<HTMLElement>(
|
|
296
|
+
`.body-cell[data-row="${rowId}"][data-column="${column}"]`,
|
|
297
|
+
);
|
|
298
|
+
if (!el) throw new Error(`Cell ${rowId}/${column} not rendered`);
|
|
299
|
+
return el;
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
expect(cellFor('row-1', 'name').classList.contains('ui-grid-row-selected')).toBe(false);
|
|
303
|
+
expect(cellFor('row-2', 'name').classList.contains('ui-grid-row-selected')).toBe(false);
|
|
304
|
+
expect(cellFor('row-3', 'name').classList.contains('ui-grid-row-selected')).toBe(false);
|
|
305
|
+
|
|
306
|
+
await act(async () => {
|
|
307
|
+
gridApi.selection.selectRow(baseData[1] as Record<string, unknown>);
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
// row-2 must be selected, the others untouched.
|
|
311
|
+
expect(cellFor('row-1', 'name').classList.contains('ui-grid-row-selected')).toBe(false);
|
|
312
|
+
expect(cellFor('row-2', 'name').classList.contains('ui-grid-row-selected')).toBe(true);
|
|
313
|
+
expect(cellFor('row-2', 'status').classList.contains('ui-grid-row-selected')).toBe(true);
|
|
314
|
+
expect(cellFor('row-3', 'name').classList.contains('ui-grid-row-selected')).toBe(false);
|
|
315
|
+
|
|
316
|
+
// Toggling expand on row-1 must insert exactly one expandable detail
|
|
317
|
+
// row and leave selection on row-2 intact.
|
|
318
|
+
await act(async () => {
|
|
319
|
+
gridApi.expandable.toggleRowExpansion(baseData[0] as Record<string, unknown>);
|
|
320
|
+
});
|
|
321
|
+
await waitFor(() => {
|
|
322
|
+
expect(shadowRoot.querySelectorAll('.expandable-row').length).toBe(1);
|
|
323
|
+
});
|
|
324
|
+
expect(cellFor('row-2', 'name').classList.contains('ui-grid-row-selected')).toBe(true);
|
|
325
|
+
});
|
|
277
326
|
});
|
package/src/UiGrid.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { createPortal } from 'react-dom';
|
|
3
3
|
import type {
|
|
4
|
+
GridBenchmarkResult,
|
|
4
5
|
GridOptions,
|
|
5
6
|
GridCellTemplateContext,
|
|
6
7
|
GridRecord,
|
|
@@ -46,6 +47,36 @@ export function UiGrid({ options, onRegisterApi, cellRenderers, className }: UiG
|
|
|
46
47
|
const optionsRef = React.useRef(options);
|
|
47
48
|
optionsRef.current = options;
|
|
48
49
|
const currentSlotColumnsRef = React.useRef<string[]>([]);
|
|
50
|
+
const wrapperRenderVersionRef = React.useRef(0);
|
|
51
|
+
const scheduledWrapperRenderVersionRef = React.useRef(0);
|
|
52
|
+
const wrapperRenderWaitersRef = React.useRef<Array<{ target: number; resolve: () => void }>>([]);
|
|
53
|
+
const benchmarkSubscriptionUnsubscribeRef = React.useRef<(() => void) | null>(null);
|
|
54
|
+
|
|
55
|
+
React.useLayoutEffect(() => {
|
|
56
|
+
wrapperRenderVersionRef.current += 1;
|
|
57
|
+
const ready = wrapperRenderWaitersRef.current.filter(
|
|
58
|
+
(waiter) => waiter.target <= wrapperRenderVersionRef.current,
|
|
59
|
+
);
|
|
60
|
+
if (ready.length === 0) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
wrapperRenderWaitersRef.current = wrapperRenderWaitersRef.current.filter(
|
|
64
|
+
(waiter) => waiter.target > wrapperRenderVersionRef.current,
|
|
65
|
+
);
|
|
66
|
+
for (const waiter of ready) {
|
|
67
|
+
waiter.resolve();
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Clean up underlying benchmark subscription if it's still active
|
|
72
|
+
React.useEffect(() => {
|
|
73
|
+
return () => {
|
|
74
|
+
if (benchmarkSubscriptionUnsubscribeRef.current) {
|
|
75
|
+
benchmarkSubscriptionUnsubscribeRef.current();
|
|
76
|
+
benchmarkSubscriptionUnsubscribeRef.current = null;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
}, []);
|
|
49
80
|
|
|
50
81
|
// Mount the vanilla element once
|
|
51
82
|
React.useEffect(() => {
|
|
@@ -77,6 +108,10 @@ export function UiGrid({ options, onRegisterApi, cellRenderers, className }: UiG
|
|
|
77
108
|
|
|
78
109
|
return () => {
|
|
79
110
|
disposed = true;
|
|
111
|
+
if (benchmarkSubscriptionUnsubscribeRef.current) {
|
|
112
|
+
benchmarkSubscriptionUnsubscribeRef.current();
|
|
113
|
+
benchmarkSubscriptionUnsubscribeRef.current = null;
|
|
114
|
+
}
|
|
80
115
|
if (el) {
|
|
81
116
|
el.removeEventListener('cellSlotsChanged', handleCellSlotsChanged);
|
|
82
117
|
el.remove();
|
|
@@ -115,6 +150,7 @@ export function UiGrid({ options, onRegisterApi, cellRenderers, className }: UiG
|
|
|
115
150
|
const value = col?.field ? getNestedValue(row, col.field) : row[entry.columnName];
|
|
116
151
|
|
|
117
152
|
if (entry.context.value !== value || entry.context.row !== row) {
|
|
153
|
+
markWrapperRenderScheduled();
|
|
118
154
|
nextSlots.set(key, {
|
|
119
155
|
...entry,
|
|
120
156
|
context: { ...entry.context, $implicit: value, value, row },
|
|
@@ -127,6 +163,77 @@ export function UiGrid({ options, onRegisterApi, cellRenderers, className }: UiG
|
|
|
127
163
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
128
164
|
}, [options.data]);
|
|
129
165
|
|
|
166
|
+
function markWrapperRenderScheduled() {
|
|
167
|
+
scheduledWrapperRenderVersionRef.current = Math.max(
|
|
168
|
+
scheduledWrapperRenderVersionRef.current,
|
|
169
|
+
wrapperRenderVersionRef.current + 1,
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function waitForScheduledWrapperRender(): Promise<void> {
|
|
174
|
+
const target = scheduledWrapperRenderVersionRef.current;
|
|
175
|
+
if (target <= wrapperRenderVersionRef.current) {
|
|
176
|
+
return Promise.resolve();
|
|
177
|
+
}
|
|
178
|
+
return new Promise<void>((resolve) => {
|
|
179
|
+
wrapperRenderWaitersRef.current.push({ target, resolve });
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function createWrappedGridApi(api: UiGridApi, opts: GridOptions): UiGridApi {
|
|
184
|
+
const benchmarkListeners = new Set<(result: GridBenchmarkResult) => void>();
|
|
185
|
+
const now = () => (typeof performance === 'undefined' ? Date.now() : performance.now());
|
|
186
|
+
// Clean up previous underlying subscription if it exists
|
|
187
|
+
if (benchmarkSubscriptionUnsubscribeRef.current) {
|
|
188
|
+
benchmarkSubscriptionUnsubscribeRef.current();
|
|
189
|
+
}
|
|
190
|
+
// Subscribe to underlying benchmarkComplete and forward to wrapper listeners
|
|
191
|
+
benchmarkSubscriptionUnsubscribeRef.current = api.core.on.benchmarkComplete((result) => {
|
|
192
|
+
for (const listener of benchmarkListeners) {
|
|
193
|
+
listener(result);
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
return {
|
|
198
|
+
...api,
|
|
199
|
+
core: {
|
|
200
|
+
...api.core,
|
|
201
|
+
on: {
|
|
202
|
+
...api.core.on,
|
|
203
|
+
benchmarkComplete: (listener) => {
|
|
204
|
+
benchmarkListeners.add(listener);
|
|
205
|
+
return () => benchmarkListeners.delete(listener);
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
benchmark: async (iterations?: number) => {
|
|
209
|
+
const loops = Math.max(1, iterations ?? opts.benchmark?.iterations ?? 25);
|
|
210
|
+
const started = now();
|
|
211
|
+
let lastResult: GridBenchmarkResult | null = null;
|
|
212
|
+
|
|
213
|
+
for (let index = 0; index < loops; index += 1) {
|
|
214
|
+
lastResult = await api.core.benchmark(1);
|
|
215
|
+
await waitForScheduledWrapperRender();
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const totalMs = now() - started;
|
|
219
|
+
|
|
220
|
+
const result: GridBenchmarkResult = {
|
|
221
|
+
iterations: loops,
|
|
222
|
+
totalMs,
|
|
223
|
+
averageMs: totalMs / loops,
|
|
224
|
+
visibleRows: lastResult?.visibleRows ?? 0,
|
|
225
|
+
renderedItems: lastResult?.renderedItems ?? 0,
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
for (const listener of benchmarkListeners) {
|
|
229
|
+
listener(result);
|
|
230
|
+
}
|
|
231
|
+
return result;
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
130
237
|
function applyOptions(el: UiGridStandaloneElement, opts: GridOptions) {
|
|
131
238
|
const renderers = cellRenderersRef.current;
|
|
132
239
|
const cellSlotColumns: string[] = [];
|
|
@@ -142,8 +249,9 @@ export function UiGrid({ options, onRegisterApi, cellRenderers, className }: UiG
|
|
|
142
249
|
const wrappedOptions: GridOptions = {
|
|
143
250
|
...opts,
|
|
144
251
|
onRegisterApi: (api) => {
|
|
145
|
-
|
|
146
|
-
|
|
252
|
+
const wrappedApi = createWrappedGridApi(api as UiGridApi, opts);
|
|
253
|
+
onRegisterApiRef.current?.(wrappedApi);
|
|
254
|
+
opts.onRegisterApi?.(wrappedApi);
|
|
147
255
|
},
|
|
148
256
|
};
|
|
149
257
|
|
|
@@ -151,8 +259,7 @@ export function UiGrid({ options, onRegisterApi, cellRenderers, className }: UiG
|
|
|
151
259
|
|
|
152
260
|
const prev = currentSlotColumnsRef.current;
|
|
153
261
|
const columnsChanged =
|
|
154
|
-
cellSlotColumns.length !== prev.length ||
|
|
155
|
-
cellSlotColumns.some((name, i) => name !== prev[i]);
|
|
262
|
+
cellSlotColumns.length !== prev.length || cellSlotColumns.some((name, i) => name !== prev[i]);
|
|
156
263
|
|
|
157
264
|
if (columnsChanged) {
|
|
158
265
|
currentSlotColumnsRef.current = cellSlotColumns;
|
|
@@ -164,6 +271,9 @@ export function UiGrid({ options, onRegisterApi, cellRenderers, className }: UiG
|
|
|
164
271
|
const detail = (event as CustomEvent<FrameworkSlotDelta<FrameworkCellSlot>>).detail;
|
|
165
272
|
const el = elementRef.current;
|
|
166
273
|
if (!el) return;
|
|
274
|
+
if (detail.removed.length > 0 || detail.added.length > 0) {
|
|
275
|
+
markWrapperRenderScheduled();
|
|
276
|
+
}
|
|
167
277
|
|
|
168
278
|
setSlots((prev) => {
|
|
169
279
|
const next = new Map(prev);
|
|
@@ -212,7 +322,11 @@ export function UiGrid({ options, onRegisterApi, cellRenderers, className }: UiG
|
|
|
212
322
|
}
|
|
213
323
|
|
|
214
324
|
return (
|
|
215
|
-
<div
|
|
325
|
+
<div
|
|
326
|
+
ref={containerRef}
|
|
327
|
+
className={className}
|
|
328
|
+
style={{ display: 'block', height: '100%', minHeight: 0 }}
|
|
329
|
+
>
|
|
216
330
|
{portals}
|
|
217
331
|
</div>
|
|
218
332
|
);
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, it } from 'vitest';
|
|
2
|
-
import {
|
|
3
|
-
activeGridEngineBackend,
|
|
4
|
-
clearRustWasmGridEngine,
|
|
5
|
-
defaultGridEngine,
|
|
6
|
-
} from '@ornery/ui-grid-core';
|
|
2
|
+
import { activeGridEngineBackend, clearRustWasmGridEngine, defaultGridEngine } from '@ornery/ui-grid-core';
|
|
7
3
|
import { registerReactUiGridWasmEngineFromModule } from './rustWasmGridEngine';
|
|
8
4
|
import { SORT_DIRECTIONS } from '@ornery/ui-grid-core';
|
|
9
|
-
import type { BuildGridPipelineContext
|
|
5
|
+
import type { BuildGridPipelineContext } from '@ornery/ui-grid-core';
|
|
10
6
|
|
|
11
7
|
function createContext(): BuildGridPipelineContext {
|
|
12
8
|
return {
|
|
@@ -37,20 +33,15 @@ describe('rustWasmGridEngine', () => {
|
|
|
37
33
|
clearRustWasmGridEngine();
|
|
38
34
|
});
|
|
39
35
|
|
|
40
|
-
it('
|
|
41
|
-
const sentinel: PipelineResult = {
|
|
42
|
-
visibleRows: [],
|
|
43
|
-
displayItems: [],
|
|
44
|
-
virtualizationEnabled: true,
|
|
45
|
-
pipelineMs: 0,
|
|
46
|
-
totalItems: 77,
|
|
47
|
-
};
|
|
48
|
-
|
|
36
|
+
it('does not install a wasm pipeline engine through the React helper', () => {
|
|
49
37
|
registerReactUiGridWasmEngineFromModule({
|
|
50
|
-
|
|
38
|
+
default: async () => undefined,
|
|
51
39
|
});
|
|
52
40
|
|
|
53
|
-
expect(defaultGridEngine.buildPipeline(createContext())).
|
|
54
|
-
|
|
41
|
+
expect(defaultGridEngine.buildPipeline(createContext()).visibleRows.map((row) => row.id)).toEqual([
|
|
42
|
+
'react-engine-spec-0',
|
|
43
|
+
'react-engine-spec-1',
|
|
44
|
+
]);
|
|
45
|
+
expect(activeGridEngineBackend()).toBe('typescript');
|
|
55
46
|
});
|
|
56
47
|
});
|
|
@@ -1,23 +1,14 @@
|
|
|
1
|
-
import type { BuildGridPipelineContext, PipelineResult } from '@ornery/ui-grid-core';
|
|
2
|
-
import { registerRustWasmGridEngine } from '@ornery/ui-grid-core';
|
|
3
|
-
|
|
4
1
|
const uiGridWasmModulePath = '../../../dist/ui-grid-wasm-web/ui_grid_wasm.js';
|
|
5
2
|
const uiGridWasmBinaryPath = '/dist/ui-grid-wasm-web/ui_grid_wasm_bg.wasm';
|
|
6
3
|
|
|
7
4
|
type UiGridWasmModule = {
|
|
8
|
-
|
|
5
|
+
default(input?: unknown): Promise<unknown>;
|
|
9
6
|
};
|
|
10
7
|
|
|
11
|
-
export function registerReactUiGridWasmEngineFromModule(
|
|
12
|
-
registerRustWasmGridEngine({
|
|
13
|
-
buildPipeline(context: BuildGridPipelineContext): PipelineResult {
|
|
14
|
-
return module.build_pipeline_js(context);
|
|
15
|
-
},
|
|
16
|
-
});
|
|
8
|
+
export function registerReactUiGridWasmEngineFromModule(_module: UiGridWasmModule): void {
|
|
17
9
|
}
|
|
18
10
|
|
|
19
11
|
export async function enableReactUiGridWasmEngine(): Promise<void> {
|
|
20
12
|
const module = await import(/* @vite-ignore */ uiGridWasmModulePath);
|
|
21
13
|
await module.default(uiGridWasmBinaryPath);
|
|
22
|
-
registerReactUiGridWasmEngineFromModule(module);
|
|
23
14
|
}
|
package/src/useGridState.ts
CHANGED
|
@@ -316,7 +316,7 @@ export interface UseGridStateResult {
|
|
|
316
316
|
nextPage: () => void;
|
|
317
317
|
previousPage: () => void;
|
|
318
318
|
onPageSizeChange: (value: string) => void;
|
|
319
|
-
runBenchmark: (iterations?: number) => GridBenchmarkResult
|
|
319
|
+
runBenchmark: (iterations?: number) => Promise<GridBenchmarkResult>;
|
|
320
320
|
exportCsv: () => void;
|
|
321
321
|
onViewportScroll: (startIndex: number) => void;
|
|
322
322
|
}
|
|
@@ -1070,11 +1070,19 @@ export function useGridState(
|
|
|
1070
1070
|
[focusRenderedCell, isCellEditable, shouldEditOnFocusFn, startCellEditFn],
|
|
1071
1071
|
);
|
|
1072
1072
|
|
|
1073
|
-
const runBenchmarkFn = useCallback((iterations?: number): GridBenchmarkResult => {
|
|
1073
|
+
const runBenchmarkFn = useCallback(async (iterations?: number): Promise<GridBenchmarkResult> => {
|
|
1074
1074
|
const safeIterations = resolveBenchmarkIterations(
|
|
1075
1075
|
iterations,
|
|
1076
1076
|
optionsRef.current.benchmark?.iterations,
|
|
1077
1077
|
);
|
|
1078
|
+
const nextFrame = () =>
|
|
1079
|
+
new Promise<void>((resolve) => {
|
|
1080
|
+
if (typeof requestAnimationFrame === 'undefined') {
|
|
1081
|
+
setTimeout(resolve, 0);
|
|
1082
|
+
return;
|
|
1083
|
+
}
|
|
1084
|
+
requestAnimationFrame(() => resolve());
|
|
1085
|
+
});
|
|
1078
1086
|
const startedAt = performance.now();
|
|
1079
1087
|
let lastResult = defaultGridEngine.buildPipeline({
|
|
1080
1088
|
options: optionsRef.current,
|
|
@@ -1118,6 +1126,7 @@ export function useGridState(
|
|
|
1118
1126
|
};
|
|
1119
1127
|
|
|
1120
1128
|
setBenchmarkResult(result);
|
|
1129
|
+
await nextFrame();
|
|
1121
1130
|
raiseGridBenchmarkComplete(gridApiRef.current!, result);
|
|
1122
1131
|
return result;
|
|
1123
1132
|
}, []);
|
package/tsconfig.json
CHANGED
package/vitest.config.ts
CHANGED
|
@@ -9,8 +9,15 @@ export default defineConfig({
|
|
|
9
9
|
},
|
|
10
10
|
},
|
|
11
11
|
test: {
|
|
12
|
-
environment: '
|
|
12
|
+
environment: 'happy-dom',
|
|
13
13
|
globals: true,
|
|
14
14
|
setupFiles: ['./src/test-setup.ts'],
|
|
15
|
+
coverage: {
|
|
16
|
+
provider: 'v8',
|
|
17
|
+
include: ['src/**/*.ts', 'src/**/*.tsx'],
|
|
18
|
+
exclude: ['src/**/*.test.ts', 'src/**/*.test.tsx', 'src/**/*.spec.ts', 'src/test-setup.ts'],
|
|
19
|
+
reporter: ['text', 'lcov', 'html'],
|
|
20
|
+
reportsDirectory: './coverage',
|
|
21
|
+
},
|
|
15
22
|
},
|
|
16
23
|
});
|