react-dev-profiler 1.0.2 → 1.1.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/dist/index.cjs +138 -108
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +146 -116
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -79,15 +79,15 @@ var s = {
|
|
|
79
79
|
backdropFilter: "blur(12px)",
|
|
80
80
|
userSelect: "none",
|
|
81
81
|
color: "#ccc",
|
|
82
|
-
fontSize: 11
|
|
82
|
+
fontSize: 11,
|
|
83
|
+
cursor: "grab",
|
|
84
|
+
touchAction: "none"
|
|
83
85
|
},
|
|
84
86
|
panelHeader: {
|
|
85
87
|
display: "flex",
|
|
86
88
|
justifyContent: "space-between",
|
|
87
89
|
alignItems: "center",
|
|
88
|
-
marginBottom: 8
|
|
89
|
-
cursor: "grab",
|
|
90
|
-
touchAction: "none"
|
|
90
|
+
marginBottom: 8
|
|
91
91
|
},
|
|
92
92
|
panelTitle: {
|
|
93
93
|
color: "#666",
|
|
@@ -118,7 +118,8 @@ var s = {
|
|
|
118
118
|
border: "none",
|
|
119
119
|
color: "#444",
|
|
120
120
|
cursor: "pointer",
|
|
121
|
-
padding:
|
|
121
|
+
padding: 4,
|
|
122
|
+
margin: -4,
|
|
122
123
|
lineHeight: 1,
|
|
123
124
|
display: "flex",
|
|
124
125
|
alignItems: "center",
|
|
@@ -133,7 +134,8 @@ var s = {
|
|
|
133
134
|
color: "#444",
|
|
134
135
|
cursor: "pointer",
|
|
135
136
|
fontSize: 13,
|
|
136
|
-
padding:
|
|
137
|
+
padding: 4,
|
|
138
|
+
margin: -4,
|
|
137
139
|
lineHeight: 1
|
|
138
140
|
},
|
|
139
141
|
body: {
|
|
@@ -182,23 +184,40 @@ var s = {
|
|
|
182
184
|
toggleBtn: {
|
|
183
185
|
position: "fixed",
|
|
184
186
|
zIndex: 99998,
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
background: "rgba(20, 20, 20, 0.9)",
|
|
187
|
+
height: 26,
|
|
188
|
+
borderRadius: 13,
|
|
189
|
+
border: "1px solid rgba(255, 255, 255, 0.08)",
|
|
190
|
+
background: "rgba(28, 28, 30, 0.92)",
|
|
190
191
|
cursor: "pointer",
|
|
191
192
|
display: "flex",
|
|
192
193
|
alignItems: "center",
|
|
193
|
-
|
|
194
|
-
padding: "0
|
|
195
|
-
backdropFilter: "blur(
|
|
194
|
+
gap: 6,
|
|
195
|
+
padding: "0 10px 0 8px",
|
|
196
|
+
backdropFilter: "blur(20px)",
|
|
197
|
+
WebkitBackdropFilter: "blur(20px)",
|
|
198
|
+
boxShadow: "0 1px 3px rgba(0, 0, 0, 0.4), inset 0 0.5px 0 rgba(255, 255, 255, 0.06)"
|
|
199
|
+
},
|
|
200
|
+
toggleDot: {
|
|
201
|
+
width: 6,
|
|
202
|
+
height: 6,
|
|
203
|
+
borderRadius: "50%",
|
|
204
|
+
flexShrink: 0
|
|
196
205
|
},
|
|
197
206
|
toggleFps: {
|
|
198
207
|
fontFamily: "'SF Mono', 'Fira Code', monospace",
|
|
199
|
-
fontSize:
|
|
200
|
-
fontWeight:
|
|
201
|
-
|
|
208
|
+
fontSize: 11,
|
|
209
|
+
fontWeight: 600,
|
|
210
|
+
color: "rgba(255, 255, 255, 0.85)",
|
|
211
|
+
letterSpacing: -0.3,
|
|
212
|
+
lineHeight: 1
|
|
213
|
+
},
|
|
214
|
+
toggleLabel: {
|
|
215
|
+
fontFamily: "'SF Mono', 'Fira Code', monospace",
|
|
216
|
+
fontSize: 9,
|
|
217
|
+
fontWeight: 500,
|
|
218
|
+
color: "rgba(255, 255, 255, 0.35)",
|
|
219
|
+
letterSpacing: 0,
|
|
220
|
+
textTransform: "lowercase"
|
|
202
221
|
},
|
|
203
222
|
footer: {
|
|
204
223
|
marginTop: 8,
|
|
@@ -210,32 +229,59 @@ var s = {
|
|
|
210
229
|
var FLASH_OUTLINE = "2px solid rgba(99, 102, 241, 0.8)";
|
|
211
230
|
|
|
212
231
|
// src/hooks.ts
|
|
232
|
+
function getEffectiveRect(el) {
|
|
233
|
+
const rect = el.getBoundingClientRect();
|
|
234
|
+
if (rect.width > 0 || rect.height > 0) return rect;
|
|
235
|
+
const children = el.children;
|
|
236
|
+
if (children.length === 0) return rect;
|
|
237
|
+
let top = Infinity, left = Infinity, bottom = -Infinity, right = -Infinity;
|
|
238
|
+
for (let i = 0; i < children.length; i++) {
|
|
239
|
+
const cr = children[i].getBoundingClientRect();
|
|
240
|
+
if (cr.width === 0 && cr.height === 0) continue;
|
|
241
|
+
top = Math.min(top, cr.top);
|
|
242
|
+
left = Math.min(left, cr.left);
|
|
243
|
+
bottom = Math.max(bottom, cr.bottom);
|
|
244
|
+
right = Math.max(right, cr.right);
|
|
245
|
+
}
|
|
246
|
+
if (top === Infinity) return rect;
|
|
247
|
+
return new DOMRect(left, top, right - left, bottom - top);
|
|
248
|
+
}
|
|
249
|
+
function getObservableChildren(el) {
|
|
250
|
+
const result = [];
|
|
251
|
+
for (let i = 0; i < el.children.length; i++) {
|
|
252
|
+
const child = el.children[i];
|
|
253
|
+
const r = child.getBoundingClientRect();
|
|
254
|
+
if (r.width > 0 || r.height > 0) result.push(child);
|
|
255
|
+
}
|
|
256
|
+
return result;
|
|
257
|
+
}
|
|
213
258
|
function useAnchorPosition(ref, position = "bottom-left") {
|
|
214
259
|
const [pos, setPos] = (0, import_react.useState)({ top: 0, left: 0 });
|
|
215
260
|
(0, import_react.useEffect)(() => {
|
|
216
261
|
if (!ref.current) return;
|
|
262
|
+
const el = ref.current;
|
|
217
263
|
const update = () => {
|
|
218
|
-
|
|
219
|
-
const rect = ref.current.getBoundingClientRect();
|
|
220
|
-
const margin = 8;
|
|
264
|
+
const rect = getEffectiveRect(el);
|
|
221
265
|
switch (position) {
|
|
222
266
|
case "top-left":
|
|
223
|
-
setPos({ top: rect.top
|
|
267
|
+
setPos({ top: rect.top, left: rect.left });
|
|
224
268
|
break;
|
|
225
269
|
case "top-right":
|
|
226
|
-
setPos({ top: rect.top
|
|
270
|
+
setPos({ top: rect.top, left: rect.right });
|
|
227
271
|
break;
|
|
228
272
|
case "bottom-right":
|
|
229
|
-
setPos({ top: rect.bottom
|
|
273
|
+
setPos({ top: rect.bottom, left: rect.right });
|
|
230
274
|
break;
|
|
231
275
|
case "bottom-left":
|
|
232
276
|
default:
|
|
233
|
-
setPos({ top: rect.bottom
|
|
277
|
+
setPos({ top: rect.bottom, left: rect.left });
|
|
234
278
|
break;
|
|
235
279
|
}
|
|
236
280
|
};
|
|
281
|
+
update();
|
|
237
282
|
const observer = new ResizeObserver(update);
|
|
238
|
-
observer.observe(
|
|
283
|
+
observer.observe(el);
|
|
284
|
+
for (const child of getObservableChildren(el)) observer.observe(child);
|
|
239
285
|
observer.observe(document.documentElement);
|
|
240
286
|
return () => observer.disconnect();
|
|
241
287
|
}, [ref, position]);
|
|
@@ -246,9 +292,10 @@ function useDraggable() {
|
|
|
246
292
|
const dragging = (0, import_react.useRef)(false);
|
|
247
293
|
const start = (0, import_react.useRef)({ x: 0, y: 0 });
|
|
248
294
|
const onPointerDown = (0, import_react.useCallback)((e) => {
|
|
295
|
+
if (e.target.closest("button, a, [data-no-drag]")) return;
|
|
249
296
|
dragging.current = true;
|
|
250
297
|
start.current = { x: e.clientX - offset.x, y: e.clientY - offset.y };
|
|
251
|
-
e.
|
|
298
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
252
299
|
}, [offset]);
|
|
253
300
|
const onPointerMove = (0, import_react.useCallback)((e) => {
|
|
254
301
|
if (!dragging.current) return;
|
|
@@ -268,21 +315,13 @@ function useDomTracker(wrapperRef, enabled) {
|
|
|
268
315
|
const dirty = (0, import_react.useRef)(true);
|
|
269
316
|
(0, import_react.useEffect)(() => {
|
|
270
317
|
if (!enabled || !wrapperRef.current) return;
|
|
271
|
-
const observer = new MutationObserver((
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
if (record.type === "attributes" && record.attributeName === "class") continue;
|
|
275
|
-
realMutation = true;
|
|
276
|
-
}
|
|
277
|
-
if (realMutation) {
|
|
278
|
-
mutations.current++;
|
|
279
|
-
dirty.current = true;
|
|
280
|
-
}
|
|
318
|
+
const observer = new MutationObserver(() => {
|
|
319
|
+
mutations.current++;
|
|
320
|
+
dirty.current = true;
|
|
281
321
|
});
|
|
282
322
|
observer.observe(wrapperRef.current, {
|
|
283
323
|
childList: true,
|
|
284
324
|
subtree: true,
|
|
285
|
-
attributes: true,
|
|
286
325
|
attributeFilter: ["style"]
|
|
287
326
|
});
|
|
288
327
|
return () => observer.disconnect();
|
|
@@ -323,18 +362,19 @@ function useRenderFlash(wrapperRef, open) {
|
|
|
323
362
|
const mutationCount = (0, import_react.useRef)(0);
|
|
324
363
|
(0, import_react.useEffect)(() => {
|
|
325
364
|
if (!open || !wrapperRef.current) return;
|
|
365
|
+
const wrapper = wrapperRef.current;
|
|
326
366
|
const observer = new MutationObserver(() => {
|
|
327
367
|
mutationCount.current++;
|
|
328
|
-
if (
|
|
329
|
-
const
|
|
330
|
-
|
|
331
|
-
|
|
368
|
+
if (mutationCount.current <= 1) return;
|
|
369
|
+
const target = getObservableChildren(wrapper)[0] ?? wrapper;
|
|
370
|
+
target.style.outline = FLASH_OUTLINE;
|
|
371
|
+
target.style.outlineOffset = "-2px";
|
|
332
372
|
setTimeout(() => {
|
|
333
|
-
|
|
334
|
-
|
|
373
|
+
target.style.outline = "";
|
|
374
|
+
target.style.outlineOffset = "";
|
|
335
375
|
}, 150);
|
|
336
376
|
});
|
|
337
|
-
observer.observe(
|
|
377
|
+
observer.observe(wrapper, { childList: true, subtree: true });
|
|
338
378
|
return () => observer.disconnect();
|
|
339
379
|
}, [wrapperRef, open]);
|
|
340
380
|
}
|
|
@@ -407,20 +447,21 @@ function StatRow({ label, value, sub, color = "#4ade80" }) {
|
|
|
407
447
|
] })
|
|
408
448
|
] });
|
|
409
449
|
}
|
|
450
|
+
var GAP = 8;
|
|
410
451
|
function getPanelStyle(pos, offset, position) {
|
|
411
452
|
const style = {
|
|
412
453
|
...s.panel,
|
|
413
454
|
transform: `translate(${offset.x}px, ${offset.y}px)`
|
|
414
455
|
};
|
|
415
456
|
if (position.startsWith("bottom")) {
|
|
416
|
-
style.bottom = window.innerHeight - pos.top;
|
|
457
|
+
style.bottom = window.innerHeight - pos.top + GAP;
|
|
417
458
|
} else {
|
|
418
|
-
style.top = pos.top;
|
|
459
|
+
style.top = pos.top + GAP;
|
|
419
460
|
}
|
|
420
461
|
if (position.endsWith("right")) {
|
|
421
|
-
style.right = window.innerWidth - pos.left;
|
|
462
|
+
style.right = window.innerWidth - pos.left + GAP;
|
|
422
463
|
} else {
|
|
423
|
-
style.left = pos.left;
|
|
464
|
+
style.left = pos.left + GAP;
|
|
424
465
|
}
|
|
425
466
|
return style;
|
|
426
467
|
}
|
|
@@ -462,7 +503,8 @@ function DevStatsPanel({
|
|
|
462
503
|
allFrameTimes.current.push(avgFrameTime);
|
|
463
504
|
const sorted = [...allFrameTimes.current].sort((a, b) => a - b);
|
|
464
505
|
const el = targetRef.current;
|
|
465
|
-
const
|
|
506
|
+
const r = el ? getEffectiveRect(el) : null;
|
|
507
|
+
const dims = r ? `${Math.round(r.width)} x ${Math.round(r.height)}` : "\u2013";
|
|
466
508
|
const perf = performance;
|
|
467
509
|
const mem = perf.memory ? Math.round(perf.memory.usedJSHeapSize / 1024 / 1024) : 0;
|
|
468
510
|
setStats({
|
|
@@ -497,23 +539,17 @@ function DevStatsPanel({
|
|
|
497
539
|
const handleExport = (0, import_react2.useCallback)(() => {
|
|
498
540
|
const payload = { timestamp: (/* @__PURE__ */ new Date()).toISOString(), ...stats };
|
|
499
541
|
const json = JSON.stringify(payload, null, 2);
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
ta.select();
|
|
512
|
-
document.execCommand("copy");
|
|
513
|
-
document.body.removeChild(ta);
|
|
514
|
-
setExported(true);
|
|
515
|
-
setTimeout(() => setExported(false), 1200);
|
|
516
|
-
}
|
|
542
|
+
const blob = new Blob([json], { type: "application/json" });
|
|
543
|
+
const url = URL.createObjectURL(blob);
|
|
544
|
+
const a = document.createElement("a");
|
|
545
|
+
a.href = url;
|
|
546
|
+
a.download = `devprofiler-${Date.now()}.json`;
|
|
547
|
+
document.body.appendChild(a);
|
|
548
|
+
a.click();
|
|
549
|
+
document.body.removeChild(a);
|
|
550
|
+
URL.revokeObjectURL(url);
|
|
551
|
+
setExported(true);
|
|
552
|
+
setTimeout(() => setExported(false), 1200);
|
|
517
553
|
}, [stats]);
|
|
518
554
|
const ftColor = stats.frameTime > 33 ? "#ef4444" : stats.frameTime > 16.67 ? "#f59e0b" : "#4ade80";
|
|
519
555
|
const rpsColor = stats.rendersPerSecond > 30 ? "#ef4444" : stats.rendersPerSecond > 10 ? "#f59e0b" : "#4ade80";
|
|
@@ -523,36 +559,26 @@ function DevStatsPanel({
|
|
|
523
559
|
const p99Color = stats.frameTimeP99 > 33 ? "#ef4444" : stats.frameTimeP99 > 16.67 ? "#f59e0b" : "#4ade80";
|
|
524
560
|
const exportStyle = exported ? { ...s.iconBtn, ...s.iconBtnActive } : s.iconBtn;
|
|
525
561
|
return (0, import_react_dom.createPortal)(
|
|
526
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: getPanelStyle(pos, offset, position), children: [
|
|
527
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
528
|
-
"
|
|
529
|
-
|
|
530
|
-
style: s.
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25z" })
|
|
547
|
-
] })
|
|
548
|
-
}
|
|
549
|
-
),
|
|
550
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { style: s.iconBtn, onClick: handleReset, title: "Reset counters", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14 1a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1h-4a1 1 0 0 1 0-2h1.6A6 6 0 0 0 2.07 7.5a1 1 0 1 1-1.97-.36A8 8 0 0 1 13 3.35V2a1 1 0 0 1 1-1zM2 15a1 1 0 0 1-1-1v-4a1 1 0 0 1 1-1h4a1 1 0 0 1 0 2H4.4A6 6 0 0 0 13.93 8.5a1 1 0 1 1 1.97.36A8 8 0 0 1 3 12.65V14a1 1 0 0 1-1 1z" }) }) }),
|
|
551
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { style: s.closeBtn, onClick: onClose, children: "\u2715" })
|
|
552
|
-
] })
|
|
553
|
-
]
|
|
554
|
-
}
|
|
555
|
-
),
|
|
562
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: getPanelStyle(pos, offset, position), ...dragHandlers, children: [
|
|
563
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: s.panelHeader, children: [
|
|
564
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: s.panelTitle, children: [
|
|
565
|
+
"Dev Profiler",
|
|
566
|
+
instanceCount > 1 && instanceId && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: s.instanceBadge, children: instanceId })
|
|
567
|
+
] }),
|
|
568
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: s.headerActions, children: [
|
|
569
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
570
|
+
"button",
|
|
571
|
+
{
|
|
572
|
+
style: exportStyle,
|
|
573
|
+
onClick: handleExport,
|
|
574
|
+
title: exported ? "Exported!" : "Export stats as JSON",
|
|
575
|
+
children: exported ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "3.5 8.5 6.5 11.5 12.5 4.5" }) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 2v8M4 7l4 4 4-4M2 14h12" }) })
|
|
576
|
+
}
|
|
577
|
+
),
|
|
578
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { style: s.iconBtn, onClick: handleReset, title: "Reset counters", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14 1a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1h-4a1 1 0 0 1 0-2h1.6A6 6 0 0 0 2.07 7.5a1 1 0 1 1-1.97-.36A8 8 0 0 1 13 3.35V2a1 1 0 0 1 1-1zM2 15a1 1 0 0 1-1-1v-4a1 1 0 0 1 1-1h4a1 1 0 0 1 0 2H4.4A6 6 0 0 0 13.93 8.5a1 1 0 1 1 1.97.36A8 8 0 0 1 3 12.65V14a1 1 0 0 1-1 1z" }) }) }),
|
|
579
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { style: s.closeBtn, onClick: onClose, children: "\u2715" })
|
|
580
|
+
] })
|
|
581
|
+
] }),
|
|
556
582
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: s.body, children: [
|
|
557
583
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: s.section, children: "Rendering" }),
|
|
558
584
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(StatRow, { label: "Frame time", value: `${stats.frameTime.toFixed(1)}ms`, sub: `${fps} fps`, color: ftColor }),
|
|
@@ -599,35 +625,35 @@ function DevStatsPanel({
|
|
|
599
625
|
var import_react3 = require("react");
|
|
600
626
|
var import_react_dom2 = require("react-dom");
|
|
601
627
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
628
|
+
var GAP2 = 8;
|
|
602
629
|
function getButtonStyle(pos, position) {
|
|
603
630
|
const style = { ...s.toggleBtn };
|
|
604
631
|
if (position.startsWith("bottom")) {
|
|
605
|
-
style.bottom = window.innerHeight - pos.top +
|
|
632
|
+
style.bottom = window.innerHeight - pos.top + GAP2;
|
|
606
633
|
} else {
|
|
607
|
-
style.top = pos.top +
|
|
634
|
+
style.top = pos.top + GAP2;
|
|
608
635
|
}
|
|
609
636
|
if (position.endsWith("right")) {
|
|
610
|
-
style.right = window.innerWidth - pos.left;
|
|
637
|
+
style.right = window.innerWidth - pos.left + GAP2;
|
|
611
638
|
} else {
|
|
612
|
-
style.left = pos.left;
|
|
639
|
+
style.left = pos.left + GAP2;
|
|
613
640
|
}
|
|
614
641
|
return style;
|
|
615
642
|
}
|
|
616
643
|
function ToggleButton({
|
|
617
644
|
targetRef,
|
|
618
645
|
onClick,
|
|
619
|
-
position = "bottom-left"
|
|
646
|
+
position = "bottom-left",
|
|
647
|
+
accentColor = "#6366f1"
|
|
620
648
|
}) {
|
|
621
649
|
const pos = useAnchorPosition(targetRef, position);
|
|
622
650
|
const [fps, setFps] = (0, import_react3.useState)(0);
|
|
623
|
-
const lastFrame = (0, import_react3.useRef)(performance.now());
|
|
624
651
|
(0, import_react3.useEffect)(() => {
|
|
625
652
|
let animId;
|
|
626
653
|
let count = 0;
|
|
627
654
|
let lastSecond = performance.now();
|
|
628
655
|
const tick = () => {
|
|
629
656
|
const now = performance.now();
|
|
630
|
-
lastFrame.current = now;
|
|
631
657
|
count++;
|
|
632
658
|
if (now - lastSecond >= 1e3) {
|
|
633
659
|
setFps(count);
|
|
@@ -639,15 +665,18 @@ function ToggleButton({
|
|
|
639
665
|
animId = requestAnimationFrame(tick);
|
|
640
666
|
return () => cancelAnimationFrame(animId);
|
|
641
667
|
}, []);
|
|
642
|
-
const fpsColor = fps < 30 ? "#ef4444" : fps < 55 ? "#f59e0b" : "#4ade80";
|
|
643
668
|
return (0, import_react_dom2.createPortal)(
|
|
644
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.
|
|
669
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
645
670
|
"button",
|
|
646
671
|
{
|
|
647
672
|
onClick,
|
|
648
673
|
title: "Dev Profiler (Ctrl+I)",
|
|
649
674
|
style: getButtonStyle(pos, position),
|
|
650
|
-
children:
|
|
675
|
+
children: [
|
|
676
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { ...s.toggleDot, background: accentColor, boxShadow: `0 0 4px ${accentColor}` } }),
|
|
677
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: s.toggleFps, children: fps }),
|
|
678
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: s.toggleLabel, children: "fps" })
|
|
679
|
+
]
|
|
651
680
|
}
|
|
652
681
|
),
|
|
653
682
|
document.body
|
|
@@ -672,7 +701,8 @@ var activeInstances = /* @__PURE__ */ new Set();
|
|
|
672
701
|
function DevProfiler({
|
|
673
702
|
children,
|
|
674
703
|
position = "bottom-left",
|
|
675
|
-
id
|
|
704
|
+
id,
|
|
705
|
+
accentColor = "#6366f1"
|
|
676
706
|
}) {
|
|
677
707
|
const wrapperRef = (0, import_react4.useRef)(null);
|
|
678
708
|
const [open, setOpen] = (0, import_react4.useState)(false);
|
|
@@ -712,7 +742,7 @@ function DevProfiler({
|
|
|
712
742
|
if (!__DEV__) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children });
|
|
713
743
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { ref: wrapperRef, style: { display: "contents" }, children: [
|
|
714
744
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react4.Profiler, { id: "DevProfiler", onRender, children }),
|
|
715
|
-
!open && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ToggleButton, { targetRef: wrapperRef, onClick: toggle, position }),
|
|
745
|
+
!open && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ToggleButton, { targetRef: wrapperRef, onClick: toggle, position, accentColor }),
|
|
716
746
|
open && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
717
747
|
DevStatsPanel,
|
|
718
748
|
{
|