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.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/DevProfiler.tsx
2
- import { Profiler, useRef as useRef4, useState as useState4, useEffect as useEffect4, useCallback as useCallback3 } from "react";
2
+ import { Profiler, useRef as useRef3, useState as useState4, useEffect as useEffect4, useCallback as useCallback3 } from "react";
3
3
 
4
4
  // src/types.ts
5
5
  var HISTORY_SIZE = 60;
@@ -53,15 +53,15 @@ var s = {
53
53
  backdropFilter: "blur(12px)",
54
54
  userSelect: "none",
55
55
  color: "#ccc",
56
- fontSize: 11
56
+ fontSize: 11,
57
+ cursor: "grab",
58
+ touchAction: "none"
57
59
  },
58
60
  panelHeader: {
59
61
  display: "flex",
60
62
  justifyContent: "space-between",
61
63
  alignItems: "center",
62
- marginBottom: 8,
63
- cursor: "grab",
64
- touchAction: "none"
64
+ marginBottom: 8
65
65
  },
66
66
  panelTitle: {
67
67
  color: "#666",
@@ -92,7 +92,8 @@ var s = {
92
92
  border: "none",
93
93
  color: "#444",
94
94
  cursor: "pointer",
95
- padding: 0,
95
+ padding: 4,
96
+ margin: -4,
96
97
  lineHeight: 1,
97
98
  display: "flex",
98
99
  alignItems: "center",
@@ -107,7 +108,8 @@ var s = {
107
108
  color: "#444",
108
109
  cursor: "pointer",
109
110
  fontSize: 13,
110
- padding: 0,
111
+ padding: 4,
112
+ margin: -4,
111
113
  lineHeight: 1
112
114
  },
113
115
  body: {
@@ -156,23 +158,40 @@ var s = {
156
158
  toggleBtn: {
157
159
  position: "fixed",
158
160
  zIndex: 99998,
159
- minWidth: 28,
160
- height: 24,
161
- borderRadius: 7,
162
- border: "1px solid #2a2a2a",
163
- background: "rgba(20, 20, 20, 0.9)",
161
+ height: 26,
162
+ borderRadius: 13,
163
+ border: "1px solid rgba(255, 255, 255, 0.08)",
164
+ background: "rgba(28, 28, 30, 0.92)",
164
165
  cursor: "pointer",
165
166
  display: "flex",
166
167
  alignItems: "center",
167
- justifyContent: "center",
168
- padding: "0 6px",
169
- backdropFilter: "blur(8px)"
168
+ gap: 6,
169
+ padding: "0 10px 0 8px",
170
+ backdropFilter: "blur(20px)",
171
+ WebkitBackdropFilter: "blur(20px)",
172
+ boxShadow: "0 1px 3px rgba(0, 0, 0, 0.4), inset 0 0.5px 0 rgba(255, 255, 255, 0.06)"
173
+ },
174
+ toggleDot: {
175
+ width: 6,
176
+ height: 6,
177
+ borderRadius: "50%",
178
+ flexShrink: 0
170
179
  },
171
180
  toggleFps: {
172
181
  fontFamily: "'SF Mono', 'Fira Code', monospace",
173
- fontSize: 10,
174
- fontWeight: 700,
175
- letterSpacing: -0.5
182
+ fontSize: 11,
183
+ fontWeight: 600,
184
+ color: "rgba(255, 255, 255, 0.85)",
185
+ letterSpacing: -0.3,
186
+ lineHeight: 1
187
+ },
188
+ toggleLabel: {
189
+ fontFamily: "'SF Mono', 'Fira Code', monospace",
190
+ fontSize: 9,
191
+ fontWeight: 500,
192
+ color: "rgba(255, 255, 255, 0.35)",
193
+ letterSpacing: 0,
194
+ textTransform: "lowercase"
176
195
  },
177
196
  footer: {
178
197
  marginTop: 8,
@@ -184,32 +203,59 @@ var s = {
184
203
  var FLASH_OUTLINE = "2px solid rgba(99, 102, 241, 0.8)";
185
204
 
186
205
  // src/hooks.ts
206
+ function getEffectiveRect(el) {
207
+ const rect = el.getBoundingClientRect();
208
+ if (rect.width > 0 || rect.height > 0) return rect;
209
+ const children = el.children;
210
+ if (children.length === 0) return rect;
211
+ let top = Infinity, left = Infinity, bottom = -Infinity, right = -Infinity;
212
+ for (let i = 0; i < children.length; i++) {
213
+ const cr = children[i].getBoundingClientRect();
214
+ if (cr.width === 0 && cr.height === 0) continue;
215
+ top = Math.min(top, cr.top);
216
+ left = Math.min(left, cr.left);
217
+ bottom = Math.max(bottom, cr.bottom);
218
+ right = Math.max(right, cr.right);
219
+ }
220
+ if (top === Infinity) return rect;
221
+ return new DOMRect(left, top, right - left, bottom - top);
222
+ }
223
+ function getObservableChildren(el) {
224
+ const result = [];
225
+ for (let i = 0; i < el.children.length; i++) {
226
+ const child = el.children[i];
227
+ const r = child.getBoundingClientRect();
228
+ if (r.width > 0 || r.height > 0) result.push(child);
229
+ }
230
+ return result;
231
+ }
187
232
  function useAnchorPosition(ref, position = "bottom-left") {
188
233
  const [pos, setPos] = useState({ top: 0, left: 0 });
189
234
  useEffect(() => {
190
235
  if (!ref.current) return;
236
+ const el = ref.current;
191
237
  const update = () => {
192
- if (!ref.current) return;
193
- const rect = ref.current.getBoundingClientRect();
194
- const margin = 8;
238
+ const rect = getEffectiveRect(el);
195
239
  switch (position) {
196
240
  case "top-left":
197
- setPos({ top: rect.top + margin, left: rect.left + margin });
241
+ setPos({ top: rect.top, left: rect.left });
198
242
  break;
199
243
  case "top-right":
200
- setPos({ top: rect.top + margin, left: rect.right - margin });
244
+ setPos({ top: rect.top, left: rect.right });
201
245
  break;
202
246
  case "bottom-right":
203
- setPos({ top: rect.bottom - margin, left: rect.right - margin });
247
+ setPos({ top: rect.bottom, left: rect.right });
204
248
  break;
205
249
  case "bottom-left":
206
250
  default:
207
- setPos({ top: rect.bottom - margin, left: rect.left + margin });
251
+ setPos({ top: rect.bottom, left: rect.left });
208
252
  break;
209
253
  }
210
254
  };
255
+ update();
211
256
  const observer = new ResizeObserver(update);
212
- observer.observe(ref.current);
257
+ observer.observe(el);
258
+ for (const child of getObservableChildren(el)) observer.observe(child);
213
259
  observer.observe(document.documentElement);
214
260
  return () => observer.disconnect();
215
261
  }, [ref, position]);
@@ -220,9 +266,10 @@ function useDraggable() {
220
266
  const dragging = useRef(false);
221
267
  const start = useRef({ x: 0, y: 0 });
222
268
  const onPointerDown = useCallback((e) => {
269
+ if (e.target.closest("button, a, [data-no-drag]")) return;
223
270
  dragging.current = true;
224
271
  start.current = { x: e.clientX - offset.x, y: e.clientY - offset.y };
225
- e.target.setPointerCapture(e.pointerId);
272
+ e.currentTarget.setPointerCapture(e.pointerId);
226
273
  }, [offset]);
227
274
  const onPointerMove = useCallback((e) => {
228
275
  if (!dragging.current) return;
@@ -242,21 +289,13 @@ function useDomTracker(wrapperRef, enabled) {
242
289
  const dirty = useRef(true);
243
290
  useEffect(() => {
244
291
  if (!enabled || !wrapperRef.current) return;
245
- const observer = new MutationObserver((records) => {
246
- let realMutation = false;
247
- for (const record of records) {
248
- if (record.type === "attributes" && record.attributeName === "class") continue;
249
- realMutation = true;
250
- }
251
- if (realMutation) {
252
- mutations.current++;
253
- dirty.current = true;
254
- }
292
+ const observer = new MutationObserver(() => {
293
+ mutations.current++;
294
+ dirty.current = true;
255
295
  });
256
296
  observer.observe(wrapperRef.current, {
257
297
  childList: true,
258
298
  subtree: true,
259
- attributes: true,
260
299
  attributeFilter: ["style"]
261
300
  });
262
301
  return () => observer.disconnect();
@@ -297,18 +336,19 @@ function useRenderFlash(wrapperRef, open) {
297
336
  const mutationCount = useRef(0);
298
337
  useEffect(() => {
299
338
  if (!open || !wrapperRef.current) return;
339
+ const wrapper = wrapperRef.current;
300
340
  const observer = new MutationObserver(() => {
301
341
  mutationCount.current++;
302
- if (!wrapperRef.current || mutationCount.current <= 1) return;
303
- const el = wrapperRef.current;
304
- el.style.outline = FLASH_OUTLINE;
305
- el.style.outlineOffset = "-2px";
342
+ if (mutationCount.current <= 1) return;
343
+ const target = getObservableChildren(wrapper)[0] ?? wrapper;
344
+ target.style.outline = FLASH_OUTLINE;
345
+ target.style.outlineOffset = "-2px";
306
346
  setTimeout(() => {
307
- el.style.outline = "";
308
- el.style.outlineOffset = "";
347
+ target.style.outline = "";
348
+ target.style.outlineOffset = "";
309
349
  }, 150);
310
350
  });
311
- observer.observe(wrapperRef.current, { childList: true, subtree: true });
351
+ observer.observe(wrapper, { childList: true, subtree: true });
312
352
  return () => observer.disconnect();
313
353
  }, [wrapperRef, open]);
314
354
  }
@@ -381,20 +421,21 @@ function StatRow({ label, value, sub, color = "#4ade80" }) {
381
421
  ] })
382
422
  ] });
383
423
  }
424
+ var GAP = 8;
384
425
  function getPanelStyle(pos, offset, position) {
385
426
  const style = {
386
427
  ...s.panel,
387
428
  transform: `translate(${offset.x}px, ${offset.y}px)`
388
429
  };
389
430
  if (position.startsWith("bottom")) {
390
- style.bottom = window.innerHeight - pos.top;
431
+ style.bottom = window.innerHeight - pos.top + GAP;
391
432
  } else {
392
- style.top = pos.top;
433
+ style.top = pos.top + GAP;
393
434
  }
394
435
  if (position.endsWith("right")) {
395
- style.right = window.innerWidth - pos.left;
436
+ style.right = window.innerWidth - pos.left + GAP;
396
437
  } else {
397
- style.left = pos.left;
438
+ style.left = pos.left + GAP;
398
439
  }
399
440
  return style;
400
441
  }
@@ -436,7 +477,8 @@ function DevStatsPanel({
436
477
  allFrameTimes.current.push(avgFrameTime);
437
478
  const sorted = [...allFrameTimes.current].sort((a, b) => a - b);
438
479
  const el = targetRef.current;
439
- const dims = el ? `${el.offsetWidth} x ${el.offsetHeight}` : "\u2013";
480
+ const r = el ? getEffectiveRect(el) : null;
481
+ const dims = r ? `${Math.round(r.width)} x ${Math.round(r.height)}` : "\u2013";
440
482
  const perf = performance;
441
483
  const mem = perf.memory ? Math.round(perf.memory.usedJSHeapSize / 1024 / 1024) : 0;
442
484
  setStats({
@@ -471,23 +513,17 @@ function DevStatsPanel({
471
513
  const handleExport = useCallback2(() => {
472
514
  const payload = { timestamp: (/* @__PURE__ */ new Date()).toISOString(), ...stats };
473
515
  const json = JSON.stringify(payload, null, 2);
474
- try {
475
- navigator.clipboard.writeText(json).then(() => {
476
- setExported(true);
477
- setTimeout(() => setExported(false), 1200);
478
- });
479
- } catch {
480
- const ta = document.createElement("textarea");
481
- ta.value = json;
482
- ta.style.position = "fixed";
483
- ta.style.opacity = "0";
484
- document.body.appendChild(ta);
485
- ta.select();
486
- document.execCommand("copy");
487
- document.body.removeChild(ta);
488
- setExported(true);
489
- setTimeout(() => setExported(false), 1200);
490
- }
516
+ const blob = new Blob([json], { type: "application/json" });
517
+ const url = URL.createObjectURL(blob);
518
+ const a = document.createElement("a");
519
+ a.href = url;
520
+ a.download = `devprofiler-${Date.now()}.json`;
521
+ document.body.appendChild(a);
522
+ a.click();
523
+ document.body.removeChild(a);
524
+ URL.revokeObjectURL(url);
525
+ setExported(true);
526
+ setTimeout(() => setExported(false), 1200);
491
527
  }, [stats]);
492
528
  const ftColor = stats.frameTime > 33 ? "#ef4444" : stats.frameTime > 16.67 ? "#f59e0b" : "#4ade80";
493
529
  const rpsColor = stats.rendersPerSecond > 30 ? "#ef4444" : stats.rendersPerSecond > 10 ? "#f59e0b" : "#4ade80";
@@ -497,36 +533,26 @@ function DevStatsPanel({
497
533
  const p99Color = stats.frameTimeP99 > 33 ? "#ef4444" : stats.frameTimeP99 > 16.67 ? "#f59e0b" : "#4ade80";
498
534
  const exportStyle = exported ? { ...s.iconBtn, ...s.iconBtnActive } : s.iconBtn;
499
535
  return createPortal(
500
- /* @__PURE__ */ jsxs("div", { style: getPanelStyle(pos, offset, position), children: [
501
- /* @__PURE__ */ jsxs(
502
- "div",
503
- {
504
- style: s.panelHeader,
505
- ...dragHandlers,
506
- children: [
507
- /* @__PURE__ */ jsxs("span", { style: s.panelTitle, children: [
508
- "Dev Profiler",
509
- instanceCount > 1 && instanceId && /* @__PURE__ */ jsx("span", { style: s.instanceBadge, children: instanceId })
510
- ] }),
511
- /* @__PURE__ */ jsxs("div", { style: s.headerActions, children: [
512
- /* @__PURE__ */ jsx(
513
- "button",
514
- {
515
- style: exportStyle,
516
- onClick: handleExport,
517
- title: exported ? "Copied!" : "Copy stats to clipboard",
518
- children: exported ? /* @__PURE__ */ jsx("svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.75.75 0 0 1 1.06-1.06L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0z" }) }) : /* @__PURE__ */ jsxs("svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "currentColor", children: [
519
- /* @__PURE__ */ jsx("path", { d: "M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25z" }),
520
- /* @__PURE__ */ 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" })
521
- ] })
522
- }
523
- ),
524
- /* @__PURE__ */ jsx("button", { style: s.iconBtn, onClick: handleReset, title: "Reset counters", children: /* @__PURE__ */ jsx("svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "currentColor", children: /* @__PURE__ */ 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" }) }) }),
525
- /* @__PURE__ */ jsx("button", { style: s.closeBtn, onClick: onClose, children: "\u2715" })
526
- ] })
527
- ]
528
- }
529
- ),
536
+ /* @__PURE__ */ jsxs("div", { style: getPanelStyle(pos, offset, position), ...dragHandlers, children: [
537
+ /* @__PURE__ */ jsxs("div", { style: s.panelHeader, children: [
538
+ /* @__PURE__ */ jsxs("span", { style: s.panelTitle, children: [
539
+ "Dev Profiler",
540
+ instanceCount > 1 && instanceId && /* @__PURE__ */ jsx("span", { style: s.instanceBadge, children: instanceId })
541
+ ] }),
542
+ /* @__PURE__ */ jsxs("div", { style: s.headerActions, children: [
543
+ /* @__PURE__ */ jsx(
544
+ "button",
545
+ {
546
+ style: exportStyle,
547
+ onClick: handleExport,
548
+ title: exported ? "Exported!" : "Export stats as JSON",
549
+ children: exported ? /* @__PURE__ */ jsx("svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("polyline", { points: "3.5 8.5 6.5 11.5 12.5 4.5" }) }) : /* @__PURE__ */ jsx("svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M8 2v8M4 7l4 4 4-4M2 14h12" }) })
550
+ }
551
+ ),
552
+ /* @__PURE__ */ jsx("button", { style: s.iconBtn, onClick: handleReset, title: "Reset counters", children: /* @__PURE__ */ jsx("svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "currentColor", children: /* @__PURE__ */ 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" }) }) }),
553
+ /* @__PURE__ */ jsx("button", { style: s.closeBtn, onClick: onClose, children: "\u2715" })
554
+ ] })
555
+ ] }),
530
556
  /* @__PURE__ */ jsxs("div", { style: s.body, children: [
531
557
  /* @__PURE__ */ jsx("span", { style: s.section, children: "Rendering" }),
532
558
  /* @__PURE__ */ jsx(StatRow, { label: "Frame time", value: `${stats.frameTime.toFixed(1)}ms`, sub: `${fps} fps`, color: ftColor }),
@@ -570,38 +596,38 @@ function DevStatsPanel({
570
596
  }
571
597
 
572
598
  // src/ToggleButton.tsx
573
- import { useState as useState3, useEffect as useEffect3, useRef as useRef3 } from "react";
599
+ import { useState as useState3, useEffect as useEffect3 } from "react";
574
600
  import { createPortal as createPortal2 } from "react-dom";
575
- import { jsx as jsx2 } from "react/jsx-runtime";
601
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
602
+ var GAP2 = 8;
576
603
  function getButtonStyle(pos, position) {
577
604
  const style = { ...s.toggleBtn };
578
605
  if (position.startsWith("bottom")) {
579
- style.bottom = window.innerHeight - pos.top + 8;
606
+ style.bottom = window.innerHeight - pos.top + GAP2;
580
607
  } else {
581
- style.top = pos.top + 8;
608
+ style.top = pos.top + GAP2;
582
609
  }
583
610
  if (position.endsWith("right")) {
584
- style.right = window.innerWidth - pos.left;
611
+ style.right = window.innerWidth - pos.left + GAP2;
585
612
  } else {
586
- style.left = pos.left;
613
+ style.left = pos.left + GAP2;
587
614
  }
588
615
  return style;
589
616
  }
590
617
  function ToggleButton({
591
618
  targetRef,
592
619
  onClick,
593
- position = "bottom-left"
620
+ position = "bottom-left",
621
+ accentColor = "#6366f1"
594
622
  }) {
595
623
  const pos = useAnchorPosition(targetRef, position);
596
624
  const [fps, setFps] = useState3(0);
597
- const lastFrame = useRef3(performance.now());
598
625
  useEffect3(() => {
599
626
  let animId;
600
627
  let count = 0;
601
628
  let lastSecond = performance.now();
602
629
  const tick = () => {
603
630
  const now = performance.now();
604
- lastFrame.current = now;
605
631
  count++;
606
632
  if (now - lastSecond >= 1e3) {
607
633
  setFps(count);
@@ -613,15 +639,18 @@ function ToggleButton({
613
639
  animId = requestAnimationFrame(tick);
614
640
  return () => cancelAnimationFrame(animId);
615
641
  }, []);
616
- const fpsColor = fps < 30 ? "#ef4444" : fps < 55 ? "#f59e0b" : "#4ade80";
617
642
  return createPortal2(
618
- /* @__PURE__ */ jsx2(
643
+ /* @__PURE__ */ jsxs2(
619
644
  "button",
620
645
  {
621
646
  onClick,
622
647
  title: "Dev Profiler (Ctrl+I)",
623
648
  style: getButtonStyle(pos, position),
624
- children: /* @__PURE__ */ jsx2("span", { style: { ...s.toggleFps, color: fpsColor }, children: fps })
649
+ children: [
650
+ /* @__PURE__ */ jsx2("span", { style: { ...s.toggleDot, background: accentColor, boxShadow: `0 0 4px ${accentColor}` } }),
651
+ /* @__PURE__ */ jsx2("span", { style: s.toggleFps, children: fps }),
652
+ /* @__PURE__ */ jsx2("span", { style: s.toggleLabel, children: "fps" })
653
+ ]
625
654
  }
626
655
  ),
627
656
  document.body
@@ -629,7 +658,7 @@ function ToggleButton({
629
658
  }
630
659
 
631
660
  // src/DevProfiler.tsx
632
- import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
661
+ import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
633
662
  var TOGGLE_EVENT = "devprofiler:toggle";
634
663
  var BOUND_KEY = "__devprofiler_bound";
635
664
  if (typeof window !== "undefined" && __DEV__ && !window[BOUND_KEY]) {
@@ -646,12 +675,13 @@ var activeInstances = /* @__PURE__ */ new Set();
646
675
  function DevProfiler({
647
676
  children,
648
677
  position = "bottom-left",
649
- id
678
+ id,
679
+ accentColor = "#6366f1"
650
680
  }) {
651
- const wrapperRef = useRef4(null);
681
+ const wrapperRef = useRef3(null);
652
682
  const [open, setOpen] = useState4(false);
653
683
  const toggle = useCallback3(() => setOpen((prev) => !prev), []);
654
- const instanceId = useRef4(id ?? `profiler-${++instanceCounter}`).current;
684
+ const instanceId = useRef3(id ?? `profiler-${++instanceCounter}`).current;
655
685
  useEffect4(() => {
656
686
  activeInstances.add(instanceId);
657
687
  return () => {
@@ -662,7 +692,7 @@ function DevProfiler({
662
692
  const renderRate = useRenderRate();
663
693
  const longTasks = useLongTasks(open);
664
694
  useRenderFlash(wrapperRef, open);
665
- const profilerData = useRef4({ ...INITIAL_PROFILER });
695
+ const profilerData = useRef3({ ...INITIAL_PROFILER });
666
696
  const onRender = useCallback3((_id, phase, actualDuration, baseDuration) => {
667
697
  profilerData.current = {
668
698
  phase,
@@ -684,9 +714,9 @@ function DevProfiler({
684
714
  return () => window.removeEventListener(TOGGLE_EVENT, handler);
685
715
  }, []);
686
716
  if (!__DEV__) return /* @__PURE__ */ jsx3(Fragment, { children });
687
- return /* @__PURE__ */ jsxs2("div", { ref: wrapperRef, style: { display: "contents" }, children: [
717
+ return /* @__PURE__ */ jsxs3("div", { ref: wrapperRef, style: { display: "contents" }, children: [
688
718
  /* @__PURE__ */ jsx3(Profiler, { id: "DevProfiler", onRender, children }),
689
- !open && /* @__PURE__ */ jsx3(ToggleButton, { targetRef: wrapperRef, onClick: toggle, position }),
719
+ !open && /* @__PURE__ */ jsx3(ToggleButton, { targetRef: wrapperRef, onClick: toggle, position, accentColor }),
690
720
  open && /* @__PURE__ */ jsx3(
691
721
  DevStatsPanel,
692
722
  {