@nice-code/state 0.7.0 → 0.8.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.
@@ -161,56 +161,61 @@ class StateDevtoolsCore {
161
161
  }
162
162
  }
163
163
  // src/devtools/browser/NiceStateDevtools.tsx
164
- import { useEffect as useEffect2, useId, useMemo, useReducer, useState as useState3 } from "react";
164
+ import {
165
+ DevtoolsLauncher,
166
+ FollowLatestToggles,
167
+ getDevtoolsDockCoordinator,
168
+ getDockSide,
169
+ PanelHeader,
170
+ ResizeHandle,
171
+ SegmentedControl as SegmentedControl2,
172
+ SplitHandle
173
+ } from "nice-devtools-shared";
174
+ import { useEffect as useEffect2, useId, useMemo, useReducer, useState as useState2 } from "react";
165
175
 
166
176
  // src/devtools/core/devtools_colors.ts
167
- var DEVTOOL_COLOR_SEMANTIC_ERROR = "#FF5C5C";
168
- var DEVTOOL_COLOR_SEMANTIC_SUCCESS = "#A3E635";
169
- var DEVTOOL_COLOR_SEMANTIC_SYSTEM = "#38BDF8";
170
- var DEVTOOL_COLOR_SEMANTIC_WARNING = "#FB923C";
171
- var DEVTOOL_COLOR_SEMANTIC_METADATA = "#A1A1AA";
172
- var DEVTOOL_COLOR_TEXT_EMPHASIS = "#f1f5f9";
173
- var DEVTOOL_COLOR_TEXT_SECONDARY = "#cbd5e1";
174
- var DEVTOOL_COLOR_TEXT_MUTED = "#64748b";
175
- var DEVTOOL_COLOR_TEXT_FAINT = "#334155";
176
- var DEVTOOL_LIST_BASE_BACKGROUND = "#0f172a";
177
- var DEVTOOL_LIST_SELECTED_BACKGROUND = "#1d2942";
178
- var DEVTOOL_DETAIL_BASE_BACKGROUND = "#0d1729";
179
- var DEVTOOL_DETAIL_HEADER_BACKGROUND = "#131f35";
180
- var DEVTOOL_SECTION_BACKGROUND = "#1e293b";
181
- var DEVTOOL_SECTION_STRING_BACKGROUND = "#0d131f";
182
- var DEVTOOL_PANEL_BORDER = "#1e293b";
183
- var DEVTOOL_PANEL_DIVIDER_BORDER = "#1d3352";
177
+ import {
178
+ DEVTOOL_COLOR_SEMANTIC_ERROR,
179
+ DEVTOOL_COLOR_SEMANTIC_METADATA,
180
+ DEVTOOL_COLOR_SEMANTIC_SUCCESS,
181
+ DEVTOOL_COLOR_SEMANTIC_SYSTEM,
182
+ DEVTOOL_COLOR_SEMANTIC_WARNING,
183
+ DEVTOOL_COLOR_TEXT_EMPHASIS,
184
+ DEVTOOL_COLOR_TEXT_FAINT,
185
+ DEVTOOL_COLOR_TEXT_MUTED,
186
+ DEVTOOL_COLOR_TEXT_SECONDARY,
187
+ DEVTOOL_DETAIL_BASE_BACKGROUND,
188
+ DEVTOOL_DETAIL_HEADER_BACKGROUND,
189
+ DEVTOOL_ERROR_BACKGROUND,
190
+ DEVTOOL_JSON_KEY,
191
+ DEVTOOL_JSON_KEYWORD,
192
+ DEVTOOL_JSON_NUMBER,
193
+ DEVTOOL_JSON_PUNCTUATION,
194
+ DEVTOOL_JSON_STRING,
195
+ DEVTOOL_LIST_BASE_BACKGROUND,
196
+ DEVTOOL_LIST_SELECTED_BACKGROUND,
197
+ DEVTOOL_PANEL_BORDER,
198
+ DEVTOOL_PANEL_DIVIDER_BORDER,
199
+ DEVTOOL_SECTION_BACKGROUND,
200
+ DEVTOOL_SECTION_STRING_BACKGROUND,
201
+ DEVTOOL_TOOLTIP_BACKGROUND,
202
+ DEVTOOL_TOOLTIP_BORDER,
203
+ DEVTOOL_TOOLTIP_TITLE_BACKGROUND,
204
+ DEVTOOL_TOOLTIP_TITLE_BOTTOM_BORDER,
205
+ MONO_FONT,
206
+ SANS_FONT
207
+ } from "nice-devtools-shared";
184
208
  var DEVTOOL_EDITOR_BACKGROUND = "#08101f";
185
- var DEVTOOL_ERROR_BACKGROUND = "#1e0a0a";
186
- var DEVTOOL_JSON_KEY = "#a5b4fc";
187
- var DEVTOOL_JSON_STRING = "#fbbf24";
188
- var DEVTOOL_JSON_NUMBER = "#34d399";
189
- var DEVTOOL_JSON_KEYWORD = "#a78bfa";
190
- var DEVTOOL_JSON_PUNCTUATION = "#475569";
191
- var MONO_FONT = "ui-monospace, 'Cascadia Code', 'Source Code Pro', monospace";
192
- var SANS_FONT = "ui-sans-serif, system-ui, sans-serif";
209
+
210
+ // src/devtools/browser/components/ChangeDetailPanel.tsx
211
+ import { SegmentedControl } from "nice-devtools-shared";
212
+
213
+ // src/devtools/browser/components/JsonView.tsx
214
+ import { JsonView, renderColoredJson } from "nice-devtools-shared";
193
215
 
194
216
  // src/devtools/browser/components/utils.ts
195
- function safeStringify(value, indent = 2) {
196
- if (value === undefined)
197
- return "undefined";
198
- if (value === null)
199
- return "null";
200
- try {
201
- return JSON.stringify(value, null, indent);
202
- } catch {
203
- return String(value);
204
- }
205
- }
206
- function formatTimestamp(ms) {
207
- return new Date(ms).toLocaleTimeString([], {
208
- hour: "2-digit",
209
- minute: "2-digit",
210
- second: "2-digit",
211
- hour12: false
212
- });
213
- }
217
+ import { safeStringify } from "nice-devtools-shared";
218
+ import { formatRelativeAge, formatTimestamp, safeStringify as safeStringify2 } from "nice-devtools-shared";
214
219
  var SOURCE_LABEL = {
215
220
  update: "UPDATE",
216
221
  replace: "REPLACE",
@@ -489,82 +494,8 @@ function formatScalar(value) {
489
494
  return String(value);
490
495
  }
491
496
 
492
- // src/devtools/browser/components/JsonView.tsx
493
- import { jsx } from "react/jsx-runtime";
494
- var JSON_TOKEN_RE = /("(?:\\.|[^"\\])*")(\s*:)?|(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)|(\btrue\b|\bfalse\b|\bnull\b|\bundefined\b)|([{}[\],])/g;
495
- function renderColoredJson(text) {
496
- const nodes = [];
497
- let last = 0;
498
- let i = 0;
499
- JSON_TOKEN_RE.lastIndex = 0;
500
- for (let m = JSON_TOKEN_RE.exec(text);m !== null; m = JSON_TOKEN_RE.exec(text)) {
501
- if (m.index > last)
502
- nodes.push(text.slice(last, m.index));
503
- const [, str, colon, num, kw, punct] = m;
504
- if (str != null) {
505
- if (colon != null) {
506
- nodes.push(/* @__PURE__ */ jsx("span", {
507
- style: { color: DEVTOOL_JSON_KEY },
508
- children: str
509
- }, i++));
510
- nodes.push(/* @__PURE__ */ jsx("span", {
511
- style: { color: DEVTOOL_JSON_PUNCTUATION },
512
- children: colon
513
- }, i++));
514
- } else {
515
- nodes.push(/* @__PURE__ */ jsx("span", {
516
- style: { color: DEVTOOL_JSON_STRING },
517
- children: str
518
- }, i++));
519
- }
520
- } else if (num != null) {
521
- nodes.push(/* @__PURE__ */ jsx("span", {
522
- style: { color: DEVTOOL_JSON_NUMBER },
523
- children: num
524
- }, i++));
525
- } else if (kw != null) {
526
- nodes.push(/* @__PURE__ */ jsx("span", {
527
- style: { color: DEVTOOL_JSON_KEYWORD },
528
- children: kw
529
- }, i++));
530
- } else if (punct != null) {
531
- nodes.push(/* @__PURE__ */ jsx("span", {
532
- style: { color: DEVTOOL_JSON_PUNCTUATION },
533
- children: punct
534
- }, i++));
535
- }
536
- last = JSON_TOKEN_RE.lastIndex;
537
- }
538
- if (last < text.length)
539
- nodes.push(text.slice(last));
540
- return nodes;
541
- }
542
- function JsonView({
543
- value,
544
- indent = 2,
545
- style
546
- }) {
547
- const text = safeStringify(value, indent);
548
- return /* @__PURE__ */ jsx("pre", {
549
- style: {
550
- margin: 0,
551
- padding: "8px 10px",
552
- borderRadius: "4px",
553
- fontSize: "11px",
554
- lineHeight: 1.5,
555
- fontFamily: MONO_FONT,
556
- background: DEVTOOL_SECTION_STRING_BACKGROUND,
557
- overflowX: "auto",
558
- whiteSpace: "pre-wrap",
559
- wordBreak: "break-word",
560
- ...style
561
- },
562
- children: renderColoredJson(text)
563
- });
564
- }
565
-
566
497
  // src/devtools/browser/components/DiffView.tsx
567
- import { jsx as jsx2, jsxs } from "react/jsx-runtime";
498
+ import { jsx, jsxs } from "react/jsx-runtime";
568
499
  var ADDED_BG = "rgba(163, 230, 53, 0.08)";
569
500
  var REMOVED_BG = "rgba(255, 92, 92, 0.08)";
570
501
  var INLINE_MAX = 40;
@@ -575,7 +506,7 @@ function DiffView({
575
506
  }) {
576
507
  const entries = computeDiff(before, after);
577
508
  if (entries.length === 0) {
578
- return /* @__PURE__ */ jsx2("div", {
509
+ return /* @__PURE__ */ jsx("div", {
579
510
  style: {
580
511
  padding: "10px",
581
512
  borderRadius: "4px",
@@ -588,9 +519,9 @@ function DiffView({
588
519
  });
589
520
  }
590
521
  const roots = [...buildTree(entries).children.values()].map(collapseChains);
591
- return /* @__PURE__ */ jsx2("div", {
522
+ return /* @__PURE__ */ jsx("div", {
592
523
  style: { display: "flex", flexDirection: "column", gap: "6px" },
593
- children: roots.map((node) => /* @__PURE__ */ jsx2(DiffNode, {
524
+ children: roots.map((node) => /* @__PURE__ */ jsx(DiffNode, {
594
525
  node,
595
526
  latestFirst
596
527
  }, node.key))
@@ -629,7 +560,7 @@ function collapseChains(node) {
629
560
  }
630
561
  function DiffNode({ node, latestFirst }) {
631
562
  if (node.entry != null && node.children.size === 0) {
632
- return /* @__PURE__ */ jsx2(DiffLeaf, {
563
+ return /* @__PURE__ */ jsx(DiffLeaf, {
633
564
  label: node.key,
634
565
  entry: node.entry,
635
566
  latestFirst
@@ -637,11 +568,11 @@ function DiffNode({ node, latestFirst }) {
637
568
  }
638
569
  return /* @__PURE__ */ jsxs("div", {
639
570
  children: [
640
- /* @__PURE__ */ jsx2("div", {
571
+ /* @__PURE__ */ jsx("div", {
641
572
  style: { color: DEVTOOL_JSON_KEY, fontFamily: MONO_FONT, fontSize: "10px", fontWeight: 600 },
642
573
  children: node.key
643
574
  }),
644
- /* @__PURE__ */ jsx2("div", {
575
+ /* @__PURE__ */ jsx("div", {
645
576
  style: {
646
577
  marginTop: "4px",
647
578
  marginLeft: "5px",
@@ -651,7 +582,7 @@ function DiffNode({ node, latestFirst }) {
651
582
  flexDirection: "column",
652
583
  gap: "5px"
653
584
  },
654
- children: [...node.children.values()].map((child) => /* @__PURE__ */ jsx2(DiffNode, {
585
+ children: [...node.children.values()].map((child) => /* @__PURE__ */ jsx(DiffNode, {
655
586
  node: child,
656
587
  latestFirst
657
588
  }, child.key))
@@ -666,25 +597,25 @@ function DiffLeaf({
666
597
  }) {
667
598
  const showRemoved = entry.kind === "removed" || entry.kind === "changed";
668
599
  const showAdded = entry.kind === "added" || entry.kind === "changed";
669
- const removed = showRemoved && /* @__PURE__ */ jsx2(InlineValue, {
600
+ const removed = showRemoved && /* @__PURE__ */ jsx(InlineValue, {
670
601
  sign: "−",
671
602
  color: DEVTOOL_COLOR_SEMANTIC_ERROR,
672
603
  background: REMOVED_BG,
673
604
  value: entry.before
674
605
  });
675
- const added = showAdded && /* @__PURE__ */ jsx2(InlineValue, {
606
+ const added = showAdded && /* @__PURE__ */ jsx(InlineValue, {
676
607
  sign: "+",
677
608
  color: DEVTOOL_COLOR_SEMANTIC_SUCCESS,
678
609
  background: ADDED_BG,
679
610
  value: entry.after
680
611
  });
681
- const removedLine = showRemoved && /* @__PURE__ */ jsx2(DiffLine, {
612
+ const removedLine = showRemoved && /* @__PURE__ */ jsx(DiffLine, {
682
613
  sign: "−",
683
614
  color: DEVTOOL_COLOR_SEMANTIC_ERROR,
684
615
  background: REMOVED_BG,
685
616
  value: entry.before
686
617
  });
687
- const addedLine = showAdded && /* @__PURE__ */ jsx2(DiffLine, {
618
+ const addedLine = showAdded && /* @__PURE__ */ jsx(DiffLine, {
688
619
  sign: "+",
689
620
  color: DEVTOOL_COLOR_SEMANTIC_SUCCESS,
690
621
  background: ADDED_BG,
@@ -702,7 +633,7 @@ function DiffLeaf({
702
633
  ]
703
634
  }),
704
635
  latestFirst ? added : removed,
705
- entry.kind === "changed" && /* @__PURE__ */ jsx2("span", {
636
+ entry.kind === "changed" && /* @__PURE__ */ jsx("span", {
706
637
  style: { color: DEVTOOL_COLOR_TEXT_MUTED },
707
638
  children: latestFirst ? "←" : "→"
708
639
  }),
@@ -717,7 +648,7 @@ function DiffLeaf({
717
648
  border: `1px solid ${DEVTOOL_SECTION_STRING_BACKGROUND}`
718
649
  },
719
650
  children: [
720
- /* @__PURE__ */ jsx2("div", {
651
+ /* @__PURE__ */ jsx("div", {
721
652
  style: {
722
653
  padding: "3px 8px",
723
654
  background: DEVTOOL_SECTION_STRING_BACKGROUND,
@@ -752,11 +683,11 @@ function InlineValue({
752
683
  wordBreak: "break-word"
753
684
  },
754
685
  children: [
755
- /* @__PURE__ */ jsx2("span", {
686
+ /* @__PURE__ */ jsx("span", {
756
687
  style: { color, fontWeight: 700, userSelect: "none" },
757
688
  children: sign
758
689
  }),
759
- /* @__PURE__ */ jsx2("span", {
690
+ /* @__PURE__ */ jsx("span", {
760
691
  children: renderColoredJson(compactStringify(value))
761
692
  })
762
693
  ]
@@ -771,11 +702,11 @@ function DiffLine({
771
702
  return /* @__PURE__ */ jsxs("div", {
772
703
  style: { display: "flex", gap: "6px", padding: "3px 8px", background },
773
704
  children: [
774
- /* @__PURE__ */ jsx2("span", {
705
+ /* @__PURE__ */ jsx("span", {
775
706
  style: { color, fontWeight: 700, flexShrink: 0, userSelect: "none" },
776
707
  children: sign
777
708
  }),
778
- /* @__PURE__ */ jsx2("span", {
709
+ /* @__PURE__ */ jsx("span", {
779
710
  style: {
780
711
  flex: 1,
781
712
  minWidth: 0,
@@ -785,7 +716,7 @@ function DiffLine({
785
716
  whiteSpace: "pre-wrap",
786
717
  wordBreak: "break-word"
787
718
  },
788
- children: renderColoredJson(safeStringify(value, 2))
719
+ children: renderColoredJson(safeStringify2(value, 2))
789
720
  })
790
721
  ]
791
722
  });
@@ -810,7 +741,7 @@ function compactStringify(value) {
810
741
  }
811
742
 
812
743
  // src/devtools/browser/components/JsonDiffView.tsx
813
- import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
744
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
814
745
  var ADDED_BG2 = "rgba(163, 230, 53, 0.13)";
815
746
  var REMOVED_BG2 = "rgba(255, 92, 92, 0.13)";
816
747
  var SURFACE_STYLE = {
@@ -824,7 +755,7 @@ var SURFACE_STYLE = {
824
755
  overflowX: "auto"
825
756
  };
826
757
  function emptyNotice(text) {
827
- return /* @__PURE__ */ jsx3("div", {
758
+ return /* @__PURE__ */ jsx2("div", {
828
759
  style: {
829
760
  padding: "10px",
830
761
  borderRadius: "4px",
@@ -840,11 +771,11 @@ function Line({ sign, color, background, text }) {
840
771
  return /* @__PURE__ */ jsxs2("div", {
841
772
  style: { display: "flex", background, padding: "0 10px", whiteSpace: "pre" },
842
773
  children: [
843
- /* @__PURE__ */ jsx3("span", {
774
+ /* @__PURE__ */ jsx2("span", {
844
775
  style: { width: "12px", flexShrink: 0, color, fontWeight: 700, userSelect: "none" },
845
776
  children: sign
846
777
  }),
847
- /* @__PURE__ */ jsx3("span", {
778
+ /* @__PURE__ */ jsx2("span", {
848
779
  style: { flex: 1, minWidth: 0 },
849
780
  children: renderColoredJson(text)
850
781
  })
@@ -858,20 +789,20 @@ function JsonDiffView({
858
789
  latestFirst = false
859
790
  }) {
860
791
  if (compress) {
861
- return /* @__PURE__ */ jsx3(CompressedDiffView, {
792
+ return /* @__PURE__ */ jsx2(CompressedDiffView, {
862
793
  before,
863
794
  after,
864
795
  side: "unified",
865
796
  latestFirst
866
797
  });
867
798
  }
868
- const ops = orderLineDiffOps(computeLineDiff(safeStringify(before, 2), safeStringify(after, 2)), latestFirst);
799
+ const ops = orderLineDiffOps(computeLineDiff(safeStringify2(before, 2), safeStringify2(after, 2)), latestFirst);
869
800
  if (!ops.some((op) => op.kind !== "common")) {
870
801
  return emptyNotice("No differences — before and after are structurally equal.");
871
802
  }
872
- return /* @__PURE__ */ jsx3("pre", {
803
+ return /* @__PURE__ */ jsx2("pre", {
873
804
  style: SURFACE_STYLE,
874
- children: ops.map((op, i) => /* @__PURE__ */ jsx3(Line, {
805
+ children: ops.map((op, i) => /* @__PURE__ */ jsx2(Line, {
875
806
  sign: op.kind === "removed" ? "−" : op.kind === "added" ? "+" : " ",
876
807
  color: op.kind === "removed" ? DEVTOOL_COLOR_SEMANTIC_ERROR : DEVTOOL_COLOR_SEMANTIC_SUCCESS,
877
808
  background: op.kind === "removed" ? REMOVED_BG2 : op.kind === "added" ? ADDED_BG2 : "transparent",
@@ -889,9 +820,9 @@ function CompressedDiffView({
889
820
  if (!lines.some((line) => line.tone === "added" || line.tone === "removed")) {
890
821
  return emptyNotice("No differences — before and after are structurally equal.");
891
822
  }
892
- return /* @__PURE__ */ jsx3("pre", {
823
+ return /* @__PURE__ */ jsx2("pre", {
893
824
  style: SURFACE_STYLE,
894
- children: lines.map((line, i) => /* @__PURE__ */ jsx3(CompressedLine, {
825
+ children: lines.map((line, i) => /* @__PURE__ */ jsx2(CompressedLine, {
895
826
  line
896
827
  }, i))
897
828
  });
@@ -902,7 +833,7 @@ function CompressedLine({ line }) {
902
833
  return /* @__PURE__ */ jsxs2("div", {
903
834
  style: { display: "flex", padding: "0 10px", whiteSpace: "pre" },
904
835
  children: [
905
- /* @__PURE__ */ jsx3("span", {
836
+ /* @__PURE__ */ jsx2("span", {
906
837
  style: { width: "12px", flexShrink: 0 }
907
838
  }),
908
839
  /* @__PURE__ */ jsxs2("span", {
@@ -920,11 +851,11 @@ function CompressedLine({ line }) {
920
851
  return /* @__PURE__ */ jsxs2("div", {
921
852
  style: { display: "flex", background, padding: "0 10px", whiteSpace: "pre" },
922
853
  children: [
923
- /* @__PURE__ */ jsx3("span", {
854
+ /* @__PURE__ */ jsx2("span", {
924
855
  style: { width: "12px", flexShrink: 0, color, fontWeight: 700, userSelect: "none" },
925
856
  children: line.sign
926
857
  }),
927
- /* @__PURE__ */ jsx3("span", {
858
+ /* @__PURE__ */ jsx2("span", {
928
859
  style: { flex: 1, minWidth: 0 },
929
860
  children: renderColoredJson(`${indent}${line.text}`)
930
861
  })
@@ -938,22 +869,22 @@ function HighlightedJsonView({
938
869
  compress = false
939
870
  }) {
940
871
  if (compress)
941
- return /* @__PURE__ */ jsx3(CompressedDiffView, {
872
+ return /* @__PURE__ */ jsx2(CompressedDiffView, {
942
873
  before,
943
874
  after,
944
875
  side
945
876
  });
946
- const ops = computeLineDiff(safeStringify(before, 2), safeStringify(after, 2));
877
+ const ops = computeLineDiff(safeStringify2(before, 2), safeStringify2(after, 2));
947
878
  const dropKind = side === "before" ? "added" : "removed";
948
879
  const highlightKind = side === "before" ? "removed" : "added";
949
880
  const background = side === "before" ? REMOVED_BG2 : ADDED_BG2;
950
881
  const color = side === "before" ? DEVTOOL_COLOR_SEMANTIC_ERROR : DEVTOOL_COLOR_SEMANTIC_SUCCESS;
951
882
  const visible = ops.filter((op) => op.kind !== dropKind);
952
- return /* @__PURE__ */ jsx3("pre", {
883
+ return /* @__PURE__ */ jsx2("pre", {
953
884
  style: SURFACE_STYLE,
954
885
  children: visible.map((op, i) => {
955
886
  const changed = op.kind === highlightKind;
956
- return /* @__PURE__ */ jsx3(Line, {
887
+ return /* @__PURE__ */ jsx2(Line, {
957
888
  sign: changed ? side === "before" ? "−" : "+" : " ",
958
889
  color,
959
890
  background: changed ? background : "transparent",
@@ -963,336 +894,8 @@ function HighlightedJsonView({
963
894
  });
964
895
  }
965
896
 
966
- // src/devtools/browser/components/PanelChrome.tsx
967
- import {
968
- useState
969
- } from "react";
970
- import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
971
- var DOCKED_SIZE_MIN = 160;
972
- var POSITION_GRID = [
973
- { key: "tl", pos: null },
974
- { key: "tc", pos: "dock-top" },
975
- { key: "tr", pos: null },
976
- { key: "ml", pos: "dock-left" },
977
- { key: "mc", pos: null },
978
- { key: "mr", pos: "dock-right" },
979
- { key: "bl", pos: null },
980
- { key: "bc", pos: "dock-bottom" },
981
- { key: "br", pos: null }
982
- ];
983
- function getDockSide(pos) {
984
- switch (pos) {
985
- case "dock-top":
986
- return "top";
987
- case "dock-left":
988
- return "left";
989
- case "dock-right":
990
- return "right";
991
- default:
992
- return "bottom";
993
- }
994
- }
995
- function PanelHeader({
996
- position,
997
- onPositionChange,
998
- onClose,
999
- onClear,
1000
- paused,
1001
- onTogglePause,
1002
- openOthers,
1003
- children
1004
- }) {
1005
- return /* @__PURE__ */ jsxs3("div", {
1006
- style: {
1007
- display: "flex",
1008
- alignItems: "center",
1009
- justifyContent: "space-between",
1010
- padding: "8px 12px",
1011
- gap: "10px",
1012
- background: DEVTOOL_SECTION_BACKGROUND,
1013
- borderBottom: `1px solid ${DEVTOOL_LIST_BASE_BACKGROUND}`,
1014
- flexShrink: 0
1015
- },
1016
- children: [
1017
- /* @__PURE__ */ jsxs3("div", {
1018
- style: { display: "flex", alignItems: "center", gap: "8px", minWidth: 0 },
1019
- children: [
1020
- /* @__PURE__ */ jsx4("span", {
1021
- style: {
1022
- color: DEVTOOL_COLOR_SEMANTIC_SYSTEM,
1023
- fontWeight: "bold",
1024
- fontSize: "11px",
1025
- whiteSpace: "nowrap"
1026
- },
1027
- children: "\uD83E\uDDE9 state"
1028
- }),
1029
- openOthers?.map((item) => /* @__PURE__ */ jsxs3("button", {
1030
- onClick: item.onOpen,
1031
- title: `Open ${item.label} devtools`,
1032
- style: {
1033
- display: "flex",
1034
- alignItems: "center",
1035
- gap: "4px",
1036
- background: DEVTOOL_LIST_BASE_BACKGROUND,
1037
- border: `1px solid ${DEVTOOL_COLOR_TEXT_FAINT}`,
1038
- borderRadius: "999px",
1039
- color: DEVTOOL_COLOR_TEXT_MUTED,
1040
- cursor: "pointer",
1041
- fontSize: "10px",
1042
- padding: "1px 7px 1px 6px",
1043
- fontFamily: SANS_FONT,
1044
- whiteSpace: "nowrap"
1045
- },
1046
- children: [
1047
- /* @__PURE__ */ jsx4("span", {
1048
- children: item.icon
1049
- }),
1050
- /* @__PURE__ */ jsx4("span", {
1051
- children: item.label
1052
- }),
1053
- item.badge != null && /* @__PURE__ */ jsx4("span", {
1054
- style: { color: DEVTOOL_COLOR_SEMANTIC_SYSTEM },
1055
- children: item.badge
1056
- })
1057
- ]
1058
- }, item.id))
1059
- ]
1060
- }),
1061
- /* @__PURE__ */ jsxs3("div", {
1062
- style: { display: "flex", gap: "10px", alignItems: "center" },
1063
- children: [
1064
- children,
1065
- /* @__PURE__ */ jsx4("button", {
1066
- onClick: onTogglePause,
1067
- title: paused ? "Resume recording" : "Pause recording",
1068
- style: chromeButtonStyle(paused ? DEVTOOL_COLOR_SEMANTIC_SYSTEM : DEVTOOL_COLOR_TEXT_MUTED),
1069
- children: paused ? "▶ resume" : "⏸ pause"
1070
- }),
1071
- onClear != null && /* @__PURE__ */ jsx4("button", {
1072
- onClick: onClear,
1073
- style: chromeButtonStyle(DEVTOOL_COLOR_TEXT_MUTED),
1074
- children: "clear"
1075
- }),
1076
- /* @__PURE__ */ jsx4(PositionPicker, {
1077
- position,
1078
- onChange: onPositionChange
1079
- }),
1080
- /* @__PURE__ */ jsx4("button", {
1081
- onClick: onClose,
1082
- style: {
1083
- ...chromeButtonStyle(DEVTOOL_COLOR_TEXT_MUTED),
1084
- fontSize: "16px",
1085
- lineHeight: "1"
1086
- },
1087
- children: "×"
1088
- })
1089
- ]
1090
- })
1091
- ]
1092
- });
1093
- }
1094
- function chromeButtonStyle(color) {
1095
- return {
1096
- background: "none",
1097
- border: "none",
1098
- color,
1099
- cursor: "pointer",
1100
- fontSize: "11px",
1101
- padding: 0,
1102
- fontFamily: SANS_FONT,
1103
- whiteSpace: "nowrap"
1104
- };
1105
- }
1106
- function PositionPicker({
1107
- position,
1108
- onChange
1109
- }) {
1110
- return /* @__PURE__ */ jsx4("div", {
1111
- title: "Move / dock panel",
1112
- style: { display: "grid", gridTemplateColumns: "repeat(3, 9px)", gap: "2px", padding: "2px" },
1113
- children: POSITION_GRID.map(({ key, pos }) => {
1114
- if (pos == null)
1115
- return /* @__PURE__ */ jsx4("div", {
1116
- style: { width: "9px", height: "9px" }
1117
- }, key);
1118
- const isTopBottom = pos === "dock-top" || pos === "dock-bottom";
1119
- const isActive = pos === position;
1120
- return /* @__PURE__ */ jsx4("div", {
1121
- title: pos,
1122
- onClick: () => onChange(pos),
1123
- style: {
1124
- width: "9px",
1125
- height: "9px",
1126
- display: "flex",
1127
- alignItems: "center",
1128
- justifyContent: "center",
1129
- cursor: "pointer"
1130
- },
1131
- children: /* @__PURE__ */ jsx4("div", {
1132
- style: {
1133
- width: isTopBottom ? "9px" : "3px",
1134
- height: isTopBottom ? "3px" : "9px",
1135
- borderRadius: "1px",
1136
- background: isActive ? DEVTOOL_COLOR_SEMANTIC_SYSTEM : DEVTOOL_COLOR_TEXT_FAINT
1137
- }
1138
- })
1139
- }, key);
1140
- })
1141
- });
1142
- }
1143
- function ResizeHandle({
1144
- dockSide,
1145
- dockedSize,
1146
- onChange
1147
- }) {
1148
- const isHoriz = dockSide === "left" || dockSide === "right";
1149
- const onMouseDown = (e) => {
1150
- e.preventDefault();
1151
- const startCoord = isHoriz ? e.clientX : e.clientY;
1152
- const startSize = dockedSize;
1153
- const maxSize = isHoriz ? window.innerWidth * 0.85 : window.innerHeight * 0.85;
1154
- const sign = dockSide === "bottom" || dockSide === "right" ? -1 : 1;
1155
- const onMove = (me) => {
1156
- const delta = (isHoriz ? me.clientX : me.clientY) - startCoord;
1157
- onChange(Math.max(DOCKED_SIZE_MIN, Math.min(maxSize, startSize + sign * delta)));
1158
- };
1159
- const onUp = () => {
1160
- window.removeEventListener("mousemove", onMove);
1161
- window.removeEventListener("mouseup", onUp);
1162
- };
1163
- window.addEventListener("mousemove", onMove);
1164
- window.addEventListener("mouseup", onUp);
1165
- };
1166
- const edgeStyle = dockSide === "bottom" ? { top: 0, left: 0, right: 0, height: "5px", cursor: "ns-resize" } : dockSide === "top" ? { bottom: 0, left: 0, right: 0, height: "5px", cursor: "ns-resize" } : dockSide === "right" ? { top: 0, bottom: 0, left: 0, width: "5px", cursor: "ew-resize" } : { top: 0, bottom: 0, right: 0, width: "5px", cursor: "ew-resize" };
1167
- return /* @__PURE__ */ jsx4("div", {
1168
- onMouseDown,
1169
- style: { position: "absolute", zIndex: 10, background: "transparent", ...edgeStyle }
1170
- });
1171
- }
1172
- var SPLIT_RATIO_MIN = 0.15;
1173
- var SPLIT_RATIO_MAX = 0.85;
1174
- function SplitHandle({
1175
- horizontal,
1176
- onRatioChange
1177
- }) {
1178
- const [hovered, setHovered] = useState(false);
1179
- const onMouseDown = (e) => {
1180
- e.preventDefault();
1181
- const container = e.currentTarget.parentElement;
1182
- if (container == null)
1183
- return;
1184
- const onMove = (me) => {
1185
- const rect = container.getBoundingClientRect();
1186
- const ratio = horizontal ? (rect.right - me.clientX) / rect.width : (rect.bottom - me.clientY) / rect.height;
1187
- onRatioChange(Math.max(SPLIT_RATIO_MIN, Math.min(SPLIT_RATIO_MAX, ratio)));
1188
- };
1189
- const onUp = () => {
1190
- window.removeEventListener("mousemove", onMove);
1191
- window.removeEventListener("mouseup", onUp);
1192
- };
1193
- window.addEventListener("mousemove", onMove);
1194
- window.addEventListener("mouseup", onUp);
1195
- };
1196
- return /* @__PURE__ */ jsx4("div", {
1197
- onMouseDown,
1198
- onMouseEnter: () => setHovered(true),
1199
- onMouseLeave: () => setHovered(false),
1200
- style: {
1201
- flex: "0 0 5px",
1202
- alignSelf: "stretch",
1203
- cursor: horizontal ? "ew-resize" : "ns-resize",
1204
- background: hovered ? DEVTOOL_COLOR_SEMANTIC_SYSTEM : "transparent",
1205
- opacity: hovered ? 0.6 : 1,
1206
- zIndex: 5
1207
- }
1208
- });
1209
- }
1210
- function SegmentedControl({
1211
- options,
1212
- value,
1213
- onChange
1214
- }) {
1215
- return /* @__PURE__ */ jsx4("div", {
1216
- style: {
1217
- display: "flex",
1218
- border: `1px solid ${DEVTOOL_COLOR_TEXT_FAINT}`,
1219
- borderRadius: "5px",
1220
- overflow: "hidden"
1221
- },
1222
- children: options.map((opt) => {
1223
- const active = opt.value === value;
1224
- return /* @__PURE__ */ jsx4("button", {
1225
- onClick: () => onChange(opt.value),
1226
- style: {
1227
- background: active ? DEVTOOL_COLOR_SEMANTIC_SYSTEM : "transparent",
1228
- color: active ? "#0f172a" : DEVTOOL_COLOR_TEXT_MUTED,
1229
- border: "none",
1230
- cursor: "pointer",
1231
- fontSize: "10px",
1232
- fontWeight: active ? 700 : 500,
1233
- padding: "3px 9px",
1234
- fontFamily: SANS_FONT
1235
- },
1236
- children: opt.label
1237
- }, opt.value);
1238
- })
1239
- });
1240
- }
1241
- function DevtoolsLauncher({ items }) {
1242
- return /* @__PURE__ */ jsx4("div", {
1243
- style: {
1244
- position: "fixed",
1245
- bottom: "16px",
1246
- right: "16px",
1247
- zIndex: 2147483646,
1248
- display: "flex",
1249
- fontFamily: MONO_FONT,
1250
- fontSize: "12px"
1251
- },
1252
- children: /* @__PURE__ */ jsx4("div", {
1253
- style: {
1254
- display: "flex",
1255
- background: DEVTOOL_SECTION_BACKGROUND,
1256
- border: `1px solid ${DEVTOOL_COLOR_TEXT_FAINT}`,
1257
- borderRadius: "6px",
1258
- overflow: "hidden",
1259
- boxShadow: "0 8px 24px rgba(0,0,0,0.35)"
1260
- },
1261
- children: items.map((item, i) => /* @__PURE__ */ jsxs3("button", {
1262
- onClick: item.onOpen,
1263
- style: {
1264
- display: "flex",
1265
- alignItems: "center",
1266
- gap: "5px",
1267
- background: "transparent",
1268
- color: DEVTOOL_COLOR_TEXT_SECONDARY,
1269
- border: "none",
1270
- borderLeft: i > 0 ? `1px solid ${DEVTOOL_COLOR_TEXT_FAINT}` : "none",
1271
- cursor: "pointer",
1272
- padding: "6px 11px",
1273
- fontFamily: MONO_FONT,
1274
- fontSize: "12px",
1275
- lineHeight: "1.5"
1276
- },
1277
- children: [
1278
- /* @__PURE__ */ jsx4("span", {
1279
- children: item.icon
1280
- }),
1281
- /* @__PURE__ */ jsx4("span", {
1282
- children: item.label
1283
- }),
1284
- item.badge != null && /* @__PURE__ */ jsx4("span", {
1285
- style: { color: DEVTOOL_COLOR_SEMANTIC_SYSTEM },
1286
- children: item.badge
1287
- })
1288
- ]
1289
- }, item.id))
1290
- })
1291
- });
1292
- }
1293
-
1294
897
  // src/devtools/browser/components/ChangeDetailPanel.tsx
1295
- import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
898
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1296
899
  function ChangeDetailPanel({
1297
900
  change,
1298
901
  onRevert,
@@ -1306,7 +909,7 @@ function ChangeDetailPanel({
1306
909
  const canRevert = change.inversePatches.length > 0;
1307
910
  const showCompressToggle = view !== "props";
1308
911
  const showOrderToggle = view === "props" || view === "diff";
1309
- return /* @__PURE__ */ jsxs4("div", {
912
+ return /* @__PURE__ */ jsxs3("div", {
1310
913
  style: {
1311
914
  flex: 1,
1312
915
  display: "flex",
@@ -1316,7 +919,7 @@ function ChangeDetailPanel({
1316
919
  background: DEVTOOL_DETAIL_BASE_BACKGROUND
1317
920
  },
1318
921
  children: [
1319
- /* @__PURE__ */ jsxs4("div", {
922
+ /* @__PURE__ */ jsxs3("div", {
1320
923
  style: {
1321
924
  padding: "8px 12px",
1322
925
  background: DEVTOOL_DETAIL_HEADER_BACKGROUND,
@@ -1327,7 +930,7 @@ function ChangeDetailPanel({
1327
930
  flexShrink: 0
1328
931
  },
1329
932
  children: [
1330
- /* @__PURE__ */ jsx5("span", {
933
+ /* @__PURE__ */ jsx3("span", {
1331
934
  style: {
1332
935
  color: DEVTOOL_COLOR_TEXT_EMPHASIS,
1333
936
  fontWeight: 600,
@@ -1339,7 +942,7 @@ function ChangeDetailPanel({
1339
942
  },
1340
943
  children: change.storeLabel
1341
944
  }),
1342
- /* @__PURE__ */ jsx5("span", {
945
+ /* @__PURE__ */ jsx3("span", {
1343
946
  style: {
1344
947
  padding: "1px 7px",
1345
948
  borderRadius: "999px",
@@ -1352,14 +955,14 @@ function ChangeDetailPanel({
1352
955
  },
1353
956
  children: SOURCE_LABEL[change.source]
1354
957
  }),
1355
- /* @__PURE__ */ jsx5("span", {
958
+ /* @__PURE__ */ jsx3("span", {
1356
959
  style: { flex: 1 }
1357
960
  }),
1358
- /* @__PURE__ */ jsx5("span", {
961
+ /* @__PURE__ */ jsx3("span", {
1359
962
  style: { color: DEVTOOL_COLOR_TEXT_MUTED, fontSize: "10px", fontFamily: MONO_FONT },
1360
963
  children: formatTimestamp(change.timestamp)
1361
964
  }),
1362
- /* @__PURE__ */ jsx5("button", {
965
+ /* @__PURE__ */ jsx3("button", {
1363
966
  onClick: () => onRevert(change),
1364
967
  disabled: !canRevert,
1365
968
  title: canRevert ? "Apply this change's inverse patches to undo it" : "No inverse patches available to revert",
@@ -1378,16 +981,16 @@ function ChangeDetailPanel({
1378
981
  })
1379
982
  ]
1380
983
  }),
1381
- /* @__PURE__ */ jsx5("div", {
984
+ /* @__PURE__ */ jsx3("div", {
1382
985
  style: {
1383
986
  padding: "6px 12px",
1384
987
  borderBottom: `1px solid ${DEVTOOL_LIST_BASE_BACKGROUND}`,
1385
988
  flexShrink: 0
1386
989
  },
1387
- children: /* @__PURE__ */ jsx5(SegmentedControl, {
990
+ children: /* @__PURE__ */ jsx3(SegmentedControl, {
1388
991
  options: [
1389
- { value: "diff", label: "Diff View" },
1390
992
  { value: "props", label: "Diff Props" },
993
+ { value: "diff", label: "Diff View" },
1391
994
  { value: "before", label: "Before" },
1392
995
  { value: "after", label: "After" }
1393
996
  ],
@@ -1395,7 +998,7 @@ function ChangeDetailPanel({
1395
998
  onChange: onViewChange
1396
999
  })
1397
1000
  }),
1398
- /* @__PURE__ */ jsxs4("div", {
1001
+ /* @__PURE__ */ jsxs3("div", {
1399
1002
  style: {
1400
1003
  flex: 1,
1401
1004
  overflowY: "auto",
@@ -1403,7 +1006,7 @@ function ChangeDetailPanel({
1403
1006
  padding: "10px 12px"
1404
1007
  },
1405
1008
  children: [
1406
- (showCompressToggle || showOrderToggle) && /* @__PURE__ */ jsxs4("div", {
1009
+ (showCompressToggle || showOrderToggle) && /* @__PURE__ */ jsxs3("div", {
1407
1010
  style: {
1408
1011
  display: "flex",
1409
1012
  flexWrap: "wrap",
@@ -1412,13 +1015,13 @@ function ChangeDetailPanel({
1412
1015
  marginBottom: "8px"
1413
1016
  },
1414
1017
  children: [
1415
- showCompressToggle && /* @__PURE__ */ jsx5(ToggleCheckbox, {
1018
+ showCompressToggle && /* @__PURE__ */ jsx3(ToggleCheckbox, {
1416
1019
  checked: compress,
1417
1020
  onChange: onCompressChange,
1418
1021
  label: "Compress to changed paths only",
1419
1022
  title: "Collapse unchanged branches, showing only the address of what changed"
1420
1023
  }),
1421
- showOrderToggle && /* @__PURE__ */ jsx5(ToggleCheckbox, {
1024
+ showOrderToggle && /* @__PURE__ */ jsx3(ToggleCheckbox, {
1422
1025
  checked: latestFirst,
1423
1026
  onChange: onLatestFirstChange,
1424
1027
  label: "Latest (+) change first",
@@ -1426,24 +1029,24 @@ function ChangeDetailPanel({
1426
1029
  })
1427
1030
  ]
1428
1031
  }),
1429
- view === "diff" && /* @__PURE__ */ jsx5(JsonDiffView, {
1032
+ view === "props" && /* @__PURE__ */ jsx3(DiffView, {
1430
1033
  before: change.prevSnapshot,
1431
1034
  after: change.snapshot,
1432
- compress,
1433
1035
  latestFirst
1434
1036
  }),
1435
- view === "props" && /* @__PURE__ */ jsx5(DiffView, {
1037
+ view === "diff" && /* @__PURE__ */ jsx3(JsonDiffView, {
1436
1038
  before: change.prevSnapshot,
1437
1039
  after: change.snapshot,
1040
+ compress,
1438
1041
  latestFirst
1439
1042
  }),
1440
- view === "before" && /* @__PURE__ */ jsx5(HighlightedJsonView, {
1043
+ view === "before" && /* @__PURE__ */ jsx3(HighlightedJsonView, {
1441
1044
  before: change.prevSnapshot,
1442
1045
  after: change.snapshot,
1443
1046
  side: "before",
1444
1047
  compress
1445
1048
  }),
1446
- view === "after" && /* @__PURE__ */ jsx5(HighlightedJsonView, {
1049
+ view === "after" && /* @__PURE__ */ jsx3(HighlightedJsonView, {
1447
1050
  before: change.prevSnapshot,
1448
1051
  after: change.snapshot,
1449
1052
  side: "after",
@@ -1460,7 +1063,7 @@ function ToggleCheckbox({
1460
1063
  label,
1461
1064
  title
1462
1065
  }) {
1463
- return /* @__PURE__ */ jsxs4("label", {
1066
+ return /* @__PURE__ */ jsxs3("label", {
1464
1067
  style: {
1465
1068
  display: "flex",
1466
1069
  alignItems: "center",
@@ -1473,7 +1076,7 @@ function ToggleCheckbox({
1473
1076
  },
1474
1077
  title,
1475
1078
  children: [
1476
- /* @__PURE__ */ jsx5("input", {
1079
+ /* @__PURE__ */ jsx3("input", {
1477
1080
  type: "checkbox",
1478
1081
  checked,
1479
1082
  onChange: (e) => onChange(e.target.checked),
@@ -1485,7 +1088,9 @@ function ToggleCheckbox({
1485
1088
  }
1486
1089
 
1487
1090
  // src/devtools/browser/components/ChangeList.tsx
1488
- import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1091
+ import { DevtoolsVirtualList } from "nice-devtools-shared";
1092
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1093
+ var getGroupKey = (group) => group.oldest.cuid;
1489
1094
  function ChangeList({
1490
1095
  groups,
1491
1096
  selectedCuid,
@@ -1493,8 +1098,14 @@ function ChangeList({
1493
1098
  showStore,
1494
1099
  style
1495
1100
  }) {
1496
- if (groups.length === 0) {
1497
- return /* @__PURE__ */ jsx6("div", {
1101
+ return /* @__PURE__ */ jsx4(DevtoolsVirtualList, {
1102
+ items: groups,
1103
+ getItemKey: getGroupKey,
1104
+ selectedKey: selectedCuid,
1105
+ estimateSize: 44,
1106
+ overscan: 12,
1107
+ style,
1108
+ empty: /* @__PURE__ */ jsx4("div", {
1498
1109
  style: {
1499
1110
  padding: "24px",
1500
1111
  textAlign: "center",
@@ -1503,17 +1114,14 @@ function ChangeList({
1503
1114
  ...style
1504
1115
  },
1505
1116
  children: "No changes recorded yet. Mutate a store to see it here."
1506
- });
1507
- }
1508
- return /* @__PURE__ */ jsx6("div", {
1509
- style,
1510
- children: groups.map((group) => /* @__PURE__ */ jsx6(ChangeRow, {
1117
+ }),
1118
+ renderItem: (group) => /* @__PURE__ */ jsx4(ChangeRow, {
1511
1119
  change: group.representative,
1512
1120
  count: group.count,
1513
1121
  selected: group.oldest.cuid === selectedCuid,
1514
1122
  onClick: () => onSelect(group.oldest.cuid),
1515
1123
  showStore
1516
- }, group.oldest.cuid))
1124
+ })
1517
1125
  });
1518
1126
  }
1519
1127
  function ChangeRow({
@@ -1524,7 +1132,7 @@ function ChangeRow({
1524
1132
  showStore
1525
1133
  }) {
1526
1134
  const sourceColor = SOURCE_COLOR[change.source];
1527
- return /* @__PURE__ */ jsxs5("div", {
1135
+ return /* @__PURE__ */ jsxs4("div", {
1528
1136
  onClick,
1529
1137
  style: {
1530
1138
  display: "flex",
@@ -1537,10 +1145,10 @@ function ChangeRow({
1537
1145
  background: selected ? DEVTOOL_LIST_SELECTED_BACKGROUND : DEVTOOL_LIST_BASE_BACKGROUND
1538
1146
  },
1539
1147
  children: [
1540
- /* @__PURE__ */ jsxs5("div", {
1148
+ /* @__PURE__ */ jsxs4("div", {
1541
1149
  style: { display: "flex", alignItems: "center", gap: "6px" },
1542
1150
  children: [
1543
- /* @__PURE__ */ jsx6("span", {
1151
+ /* @__PURE__ */ jsx4("span", {
1544
1152
  style: {
1545
1153
  color: DEVTOOL_COLOR_TEXT_MUTED,
1546
1154
  fontSize: "10px",
@@ -1549,11 +1157,11 @@ function ChangeRow({
1549
1157
  },
1550
1158
  children: formatTimestamp(change.timestamp)
1551
1159
  }),
1552
- /* @__PURE__ */ jsx6(Badge, {
1160
+ /* @__PURE__ */ jsx4(Badge, {
1553
1161
  color: sourceColor,
1554
1162
  children: SOURCE_LABEL[change.source]
1555
1163
  }),
1556
- count > 1 && /* @__PURE__ */ jsxs5("span", {
1164
+ count > 1 && /* @__PURE__ */ jsxs4("span", {
1557
1165
  title: `${count} consecutive identical updates`,
1558
1166
  style: {
1559
1167
  flexShrink: 0,
@@ -1570,7 +1178,7 @@ function ChangeRow({
1570
1178
  count
1571
1179
  ]
1572
1180
  }),
1573
- showStore && /* @__PURE__ */ jsx6("span", {
1181
+ showStore && /* @__PURE__ */ jsx4("span", {
1574
1182
  style: {
1575
1183
  color: DEVTOOL_COLOR_SEMANTIC_SYSTEM,
1576
1184
  fontSize: "10px",
@@ -1581,10 +1189,10 @@ function ChangeRow({
1581
1189
  },
1582
1190
  children: change.storeLabel
1583
1191
  }),
1584
- /* @__PURE__ */ jsx6("span", {
1192
+ /* @__PURE__ */ jsx4("span", {
1585
1193
  style: { flex: 1 }
1586
1194
  }),
1587
- change.patches.length > 0 && /* @__PURE__ */ jsxs5("span", {
1195
+ change.patches.length > 0 && /* @__PURE__ */ jsxs4("span", {
1588
1196
  style: { color: DEVTOOL_COLOR_TEXT_FAINT, fontSize: "10px", flexShrink: 0 },
1589
1197
  children: [
1590
1198
  change.patches.length,
@@ -1594,7 +1202,7 @@ function ChangeRow({
1594
1202
  })
1595
1203
  ]
1596
1204
  }),
1597
- /* @__PURE__ */ jsx6("div", {
1205
+ /* @__PURE__ */ jsx4("div", {
1598
1206
  style: {
1599
1207
  color: DEVTOOL_COLOR_TEXT_SECONDARY,
1600
1208
  fontSize: "11px",
@@ -1609,7 +1217,7 @@ function ChangeRow({
1609
1217
  });
1610
1218
  }
1611
1219
  function Badge({ color, children }) {
1612
- return /* @__PURE__ */ jsx6("span", {
1220
+ return /* @__PURE__ */ jsx4("span", {
1613
1221
  style: {
1614
1222
  flexShrink: 0,
1615
1223
  padding: "1px 6px",
@@ -1626,38 +1234,21 @@ function Badge({ color, children }) {
1626
1234
  }
1627
1235
 
1628
1236
  // src/devtools/browser/components/StateInspector.tsx
1629
- import { useEffect, useState as useState2 } from "react";
1237
+ import { useEffect, useState } from "react";
1630
1238
 
1631
1239
  // src/devtools/browser/components/SectionLabel.tsx
1632
- import { jsx as jsx7 } from "react/jsx-runtime";
1633
- function SectionLabel({
1634
- label,
1635
- color = DEVTOOL_COLOR_SEMANTIC_SYSTEM
1636
- }) {
1637
- return /* @__PURE__ */ jsx7("div", {
1638
- style: {
1639
- color,
1640
- fontSize: "0.85em",
1641
- marginBottom: "3px",
1642
- textTransform: "uppercase",
1643
- letterSpacing: "0.05em",
1644
- fontWeight: 500,
1645
- textAlign: "left"
1646
- },
1647
- children: label
1648
- });
1649
- }
1240
+ import { SectionLabel } from "nice-devtools-shared";
1650
1241
 
1651
1242
  // src/devtools/browser/components/StateInspector.tsx
1652
- import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
1243
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1653
1244
  function StateInspector({
1654
1245
  store,
1655
1246
  onApply
1656
1247
  }) {
1657
- const liveText = safeStringify(store.currentState, 2);
1658
- const [draft, setDraft] = useState2(liveText);
1659
- const [dirty, setDirty] = useState2(false);
1660
- const [error, setError] = useState2(null);
1248
+ const liveText = safeStringify2(store.currentState, 2);
1249
+ const [draft, setDraft] = useState(liveText);
1250
+ const [dirty, setDirty] = useState(false);
1251
+ const [error, setError] = useState(null);
1661
1252
  useEffect(() => {
1662
1253
  setDraft(liveText);
1663
1254
  setDirty(false);
@@ -1689,7 +1280,7 @@ function StateInspector({
1689
1280
  setDirty(false);
1690
1281
  setError(null);
1691
1282
  };
1692
- return /* @__PURE__ */ jsxs6("div", {
1283
+ return /* @__PURE__ */ jsxs5("div", {
1693
1284
  style: {
1694
1285
  flex: 1,
1695
1286
  display: "flex",
@@ -1699,7 +1290,7 @@ function StateInspector({
1699
1290
  background: DEVTOOL_DETAIL_BASE_BACKGROUND
1700
1291
  },
1701
1292
  children: [
1702
- /* @__PURE__ */ jsxs6("div", {
1293
+ /* @__PURE__ */ jsxs5("div", {
1703
1294
  style: {
1704
1295
  flex: 1,
1705
1296
  minHeight: 0,
@@ -1708,19 +1299,19 @@ function StateInspector({
1708
1299
  padding: "10px 12px 8px"
1709
1300
  },
1710
1301
  children: [
1711
- /* @__PURE__ */ jsx8(SectionLabel, {
1302
+ /* @__PURE__ */ jsx5(SectionLabel, {
1712
1303
  label: "Current state"
1713
1304
  }),
1714
- /* @__PURE__ */ jsx8("div", {
1305
+ /* @__PURE__ */ jsx5("div", {
1715
1306
  style: { flex: 1, minHeight: 0, overflow: "auto" },
1716
- children: /* @__PURE__ */ jsx8(JsonView, {
1307
+ children: /* @__PURE__ */ jsx5(JsonView, {
1717
1308
  value: store.currentState,
1718
1309
  style: { minHeight: "100%" }
1719
1310
  })
1720
1311
  })
1721
1312
  ]
1722
1313
  }),
1723
- /* @__PURE__ */ jsxs6("div", {
1314
+ /* @__PURE__ */ jsxs5("div", {
1724
1315
  style: {
1725
1316
  flex: 1,
1726
1317
  minHeight: 0,
@@ -1730,7 +1321,7 @@ function StateInspector({
1730
1321
  borderTop: `1px solid ${DEVTOOL_PANEL_DIVIDER_BORDER}`
1731
1322
  },
1732
1323
  children: [
1733
- /* @__PURE__ */ jsxs6("div", {
1324
+ /* @__PURE__ */ jsxs5("div", {
1734
1325
  style: {
1735
1326
  display: "flex",
1736
1327
  alignItems: "center",
@@ -1738,18 +1329,18 @@ function StateInspector({
1738
1329
  marginBottom: "3px"
1739
1330
  },
1740
1331
  children: [
1741
- /* @__PURE__ */ jsx8(SectionLabel, {
1332
+ /* @__PURE__ */ jsx5(SectionLabel, {
1742
1333
  label: "Edit & apply",
1743
1334
  color: DEVTOOL_COLOR_SEMANTIC_WARNING
1744
1335
  }),
1745
- dirty && /* @__PURE__ */ jsx8("button", {
1336
+ dirty && /* @__PURE__ */ jsx5("button", {
1746
1337
  onClick: reload,
1747
1338
  style: linkButtonStyle(DEVTOOL_COLOR_TEXT_MUTED),
1748
1339
  children: "reload from store"
1749
1340
  })
1750
1341
  ]
1751
1342
  }),
1752
- /* @__PURE__ */ jsx8("textarea", {
1343
+ /* @__PURE__ */ jsx5("textarea", {
1753
1344
  value: draft,
1754
1345
  spellCheck: false,
1755
1346
  onChange: (e) => onEdit(e.target.value),
@@ -1769,7 +1360,7 @@ function StateInspector({
1769
1360
  lineHeight: 1.5
1770
1361
  }
1771
1362
  }),
1772
- error != null && /* @__PURE__ */ jsx8("div", {
1363
+ error != null && /* @__PURE__ */ jsx5("div", {
1773
1364
  style: {
1774
1365
  marginTop: "6px",
1775
1366
  padding: "6px 8px",
@@ -1782,9 +1373,9 @@ function StateInspector({
1782
1373
  },
1783
1374
  children: error
1784
1375
  }),
1785
- /* @__PURE__ */ jsx8("div", {
1376
+ /* @__PURE__ */ jsx5("div", {
1786
1377
  style: { display: "flex", gap: "8px", marginTop: "8px", flexShrink: 0 },
1787
- children: /* @__PURE__ */ jsx8("button", {
1378
+ children: /* @__PURE__ */ jsx5("button", {
1788
1379
  onClick: apply,
1789
1380
  disabled: !dirty,
1790
1381
  style: {
@@ -1819,14 +1410,14 @@ function linkButtonStyle(color) {
1819
1410
  }
1820
1411
 
1821
1412
  // src/devtools/browser/components/StoreTabs.tsx
1822
- import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
1413
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
1823
1414
  function StoreTabs({
1824
1415
  stores,
1825
1416
  selectedStoreId,
1826
1417
  onSelect,
1827
1418
  includeAll = true
1828
1419
  }) {
1829
- return /* @__PURE__ */ jsxs7("div", {
1420
+ return /* @__PURE__ */ jsxs6("div", {
1830
1421
  style: {
1831
1422
  display: "flex",
1832
1423
  gap: "6px",
@@ -1834,19 +1425,20 @@ function StoreTabs({
1834
1425
  overflowX: "auto",
1835
1426
  background: DEVTOOL_LIST_BASE_BACKGROUND,
1836
1427
  borderBottom: `1px solid ${DEVTOOL_SECTION_BACKGROUND}`,
1428
+ flexWrap: "wrap",
1837
1429
  flexShrink: 0
1838
1430
  },
1839
1431
  children: [
1840
- includeAll && /* @__PURE__ */ jsx9(Pill, {
1432
+ includeAll && /* @__PURE__ */ jsx6(Pill, {
1841
1433
  active: selectedStoreId == null,
1842
1434
  onClick: () => onSelect(null),
1843
1435
  label: "all"
1844
1436
  }),
1845
- stores.length === 0 && /* @__PURE__ */ jsx9("span", {
1437
+ stores.length === 0 && /* @__PURE__ */ jsx6("span", {
1846
1438
  style: { color: DEVTOOL_COLOR_TEXT_MUTED, fontSize: "11px", padding: "2px 0" },
1847
1439
  children: "no stores registered"
1848
1440
  }),
1849
- stores.map((store) => /* @__PURE__ */ jsx9(Pill, {
1441
+ stores.map((store) => /* @__PURE__ */ jsx6(Pill, {
1850
1442
  active: selectedStoreId === store.id,
1851
1443
  onClick: () => onSelect(store.id),
1852
1444
  label: store.label,
@@ -1861,7 +1453,7 @@ function Pill({
1861
1453
  label,
1862
1454
  count
1863
1455
  }) {
1864
- return /* @__PURE__ */ jsxs7("button", {
1456
+ return /* @__PURE__ */ jsxs6("button", {
1865
1457
  onClick,
1866
1458
  style: {
1867
1459
  display: "flex",
@@ -1880,7 +1472,7 @@ function Pill({
1880
1472
  },
1881
1473
  children: [
1882
1474
  label,
1883
- count != null && count > 0 && /* @__PURE__ */ jsx9("span", {
1475
+ count != null && count > 0 && /* @__PURE__ */ jsx6("span", {
1884
1476
  style: {
1885
1477
  color: active ? DEVTOOL_COLOR_SEMANTIC_SYSTEM : DEVTOOL_COLOR_TEXT_FAINT,
1886
1478
  fontSize: "10px"
@@ -1891,115 +1483,8 @@ function Pill({
1891
1483
  });
1892
1484
  }
1893
1485
 
1894
- // src/devtools/browser/devtools_dock.ts
1895
- var GLOBAL_KEY = "__NICE_DEVTOOLS_DOCK__";
1896
- var VERSION = 4;
1897
- function createCoordinator() {
1898
- const panels = new Map;
1899
- const listeners = new Set;
1900
- function toRef(panel) {
1901
- return {
1902
- id: panel.id,
1903
- label: panel.label,
1904
- icon: panel.icon,
1905
- badge: panel.badge,
1906
- onOpen: panel.onOpen
1907
- };
1908
- }
1909
- function applyBodyMargins() {
1910
- if (typeof document === "undefined")
1911
- return;
1912
- const margins = { top: 0, bottom: 0, left: 0, right: 0 };
1913
- for (const panel of panels.values()) {
1914
- if (panel.open)
1915
- margins[panel.side] += panel.size;
1916
- }
1917
- const sides = ["top", "bottom", "left", "right"];
1918
- for (const side of sides) {
1919
- if (margins[side] > 0) {
1920
- document.body.style.setProperty(`margin-${side}`, `${margins[side]}px`);
1921
- } else {
1922
- document.body.style.removeProperty(`margin-${side}`);
1923
- }
1924
- }
1925
- }
1926
- function notify() {
1927
- applyBodyMargins();
1928
- for (const listener of listeners)
1929
- listener();
1930
- }
1931
- return {
1932
- version: VERSION,
1933
- register(panel) {
1934
- panels.set(panel.id, { ...panel });
1935
- notify();
1936
- return () => {
1937
- panels.delete(panel.id);
1938
- notify();
1939
- };
1940
- },
1941
- update(id, next) {
1942
- const existing = panels.get(id);
1943
- if (existing == null)
1944
- return;
1945
- if (existing.side === next.side && existing.size === next.size && existing.open === next.open && existing.badge === next.badge) {
1946
- return;
1947
- }
1948
- panels.set(id, { ...existing, ...next });
1949
- notify();
1950
- },
1951
- getView(id) {
1952
- const list = [...panels.values()];
1953
- const anyOpen = list.some((p) => p.open);
1954
- const firstId = list.length > 0 ? list[0].id : null;
1955
- let dockOffset = 0;
1956
- let stacked = false;
1957
- const self = panels.get(id);
1958
- if (self != null && self.open) {
1959
- let seenSelf = false;
1960
- for (const panel of list) {
1961
- if (panel.id === id) {
1962
- seenSelf = true;
1963
- continue;
1964
- }
1965
- if (panel.open && panel.side === self.side) {
1966
- stacked = true;
1967
- if (!seenSelf)
1968
- dockOffset += panel.size;
1969
- }
1970
- }
1971
- }
1972
- return {
1973
- dockOffset,
1974
- stacked,
1975
- anyOpen,
1976
- isPrimary: id === firstId,
1977
- devtools: list.map(toRef),
1978
- otherClosed: list.filter((p) => !p.open && p.id !== id).map(toRef)
1979
- };
1980
- },
1981
- subscribe(listener) {
1982
- listeners.add(listener);
1983
- return () => {
1984
- listeners.delete(listener);
1985
- };
1986
- }
1987
- };
1988
- }
1989
- function getDevtoolsDockCoordinator() {
1990
- if (typeof window === "undefined")
1991
- return createCoordinator();
1992
- const host = window;
1993
- const existing = host[GLOBAL_KEY];
1994
- if (existing != null && existing.version === VERSION)
1995
- return existing;
1996
- const created = createCoordinator();
1997
- host[GLOBAL_KEY] = created;
1998
- return created;
1999
- }
2000
-
2001
1486
  // src/devtools/browser/NiceStateDevtools.tsx
2002
- import { jsx as jsx10, jsxs as jsxs8, Fragment } from "react/jsx-runtime";
1487
+ import { jsx as jsx7, jsxs as jsxs7, Fragment } from "react/jsx-runtime";
2003
1488
  if (typeof document !== "undefined" && !document.getElementById("__nice-state-devtools-styles")) {
2004
1489
  const style = document.createElement("style");
2005
1490
  style.id = "__nice-state-devtools-styles";
@@ -2013,12 +1498,20 @@ if (typeof document !== "undefined" && !document.getElementById("__nice-state-de
2013
1498
  #__nice-state-devtools-panel ::-webkit-scrollbar-thumb { background: #334155; border-radius: 2px; }
2014
1499
  #__nice-state-devtools-panel ::-webkit-scrollbar-thumb:hover { background: #475569; }
2015
1500
  #__nice-state-devtools-panel ::-webkit-scrollbar-corner { background: transparent; }
1501
+ /* Shield the panel's native form controls from the host app's global element
1502
+ styles (e.g. a bare \`input {}\`/\`button {}\` rule). \`all: revert\` drops them
1503
+ to the UA baseline the panel is authored against; the panel's own inline
1504
+ styles still win, so its look is unchanged across any host. */
1505
+ #__nice-state-devtools-panel input,
1506
+ #__nice-state-devtools-panel button,
1507
+ #__nice-state-devtools-panel select,
1508
+ #__nice-state-devtools-panel textarea { all: revert; font-family: inherit; }
2016
1509
  `;
2017
1510
  document.head?.appendChild(style);
2018
1511
  }
2019
1512
  var PREFS_KEY = "__nice-state-devtools-prefs";
2020
1513
  var DOCKED_HEIGHT_DEFAULT = 340;
2021
- var DOCKED_WIDTH_DEFAULT = 460;
1514
+ var DOCKED_WIDTH_DEFAULT = 330;
2022
1515
  var DETAIL_RATIO_DEFAULT = 0.5;
2023
1516
  var DOCK_POSITIONS = ["dock-bottom", "dock-top", "dock-left", "dock-right"];
2024
1517
  function isDockPosition(value) {
@@ -2034,7 +1527,7 @@ function readPrefs(defaultPosition, initialOpen) {
2034
1527
  stayOnLatest: true,
2035
1528
  followLatestOnSelect: true,
2036
1529
  compressDiff: true,
2037
- detailView: "diff",
1530
+ detailView: "props",
2038
1531
  diffLatestFirst: true
2039
1532
  };
2040
1533
  try {
@@ -2061,20 +1554,20 @@ function NiceStateDevtools({ forceEnable, ...props }) {
2061
1554
  if (!forceEnable && process["env"]["NODE_ENV"] !== "development") {
2062
1555
  return null;
2063
1556
  }
2064
- return /* @__PURE__ */ jsx10(NiceStateDevtools_Panel, {
1557
+ return /* @__PURE__ */ jsx7(NiceStateDevtools_Panel, {
2065
1558
  ...props
2066
1559
  });
2067
1560
  }
2068
1561
  function NiceStateDevtools_Panel({
2069
1562
  core,
2070
- position: defaultPosition = "dock-bottom",
1563
+ position: defaultPosition = "dock-right",
2071
1564
  initialOpen = false
2072
1565
  }) {
2073
- const [prefs, setPrefsRaw] = useState3(() => readPrefs(defaultPosition, initialOpen));
2074
- const [snapshot, setSnapshot] = useState3(EMPTY_SNAPSHOT);
2075
- const [mode, setMode] = useState3("timeline");
2076
- const [storeFilter, setStoreFilter] = useState3(null);
2077
- const [selectedChangeCuid, setSelectedChangeCuid] = useState3(null);
1566
+ const [prefs, setPrefsRaw] = useState2(() => readPrefs(defaultPosition, initialOpen));
1567
+ const [snapshot, setSnapshot] = useState2(EMPTY_SNAPSHOT);
1568
+ const [mode, setMode] = useState2("timeline");
1569
+ const [storeFilter, setStoreFilter] = useState2(null);
1570
+ const [selectedChangeCuid, setSelectedChangeCuid] = useState2(null);
2078
1571
  useEffect2(() => core.subscribe(setSnapshot), [core]);
2079
1572
  const setPrefs = (update) => {
2080
1573
  setPrefsRaw((prev) => ({ ...prev, ...update }));
@@ -2155,7 +1648,7 @@ function NiceStateDevtools_Panel({
2155
1648
  };
2156
1649
  if (!isOpen) {
2157
1650
  if (view.isPrimary && !view.anyOpen) {
2158
- return /* @__PURE__ */ jsx10(DevtoolsLauncher, {
1651
+ return /* @__PURE__ */ jsx7(DevtoolsLauncher, {
2159
1652
  items: view.devtools
2160
1653
  });
2161
1654
  }
@@ -2196,16 +1689,17 @@ function NiceStateDevtools_Panel({
2196
1689
  borderRadius: view.stacked ? "0" : "8px 0 0 8px"
2197
1690
  }
2198
1691
  };
2199
- return /* @__PURE__ */ jsxs8("div", {
1692
+ return /* @__PURE__ */ jsxs7("div", {
2200
1693
  id: "__nice-state-devtools-panel",
2201
1694
  style: panelStyle,
2202
1695
  children: [
2203
- /* @__PURE__ */ jsx10(ResizeHandle, {
1696
+ /* @__PURE__ */ jsx7(ResizeHandle, {
2204
1697
  dockSide,
2205
1698
  dockedSize,
2206
1699
  onChange: (size) => setPrefs(isHorizDock ? { dockedHeight: size } : { dockedWidth: size })
2207
1700
  }),
2208
- /* @__PURE__ */ jsx10(PanelHeader, {
1701
+ /* @__PURE__ */ jsx7(PanelHeader, {
1702
+ title: "\uD83E\uDDE9 state",
2209
1703
  position,
2210
1704
  onPositionChange: (p) => setPrefs({ position: p }),
2211
1705
  onClose: () => setPrefs({ isOpen: false }),
@@ -2216,7 +1710,7 @@ function NiceStateDevtools_Panel({
2216
1710
  paused,
2217
1711
  onTogglePause: () => core.togglePaused(),
2218
1712
  openOthers: view.otherClosed,
2219
- children: /* @__PURE__ */ jsx10(SegmentedControl, {
1713
+ children: /* @__PURE__ */ jsx7(SegmentedControl2, {
2220
1714
  options: [
2221
1715
  { value: "timeline", label: "Timeline" },
2222
1716
  { value: "state", label: "State" }
@@ -2225,18 +1719,18 @@ function NiceStateDevtools_Panel({
2225
1719
  onChange: setMode
2226
1720
  })
2227
1721
  }),
2228
- /* @__PURE__ */ jsx10(StoreTabs, {
1722
+ /* @__PURE__ */ jsx7(StoreTabs, {
2229
1723
  stores,
2230
1724
  selectedStoreId: mode === "state" ? activeStore?.id ?? null : storeFilter,
2231
1725
  onSelect: setStoreFilter,
2232
1726
  includeAll: mode === "timeline"
2233
1727
  }),
2234
- mode === "state" ? activeStore != null ? /* @__PURE__ */ jsx10(StateInspector, {
1728
+ mode === "state" ? activeStore != null ? /* @__PURE__ */ jsx7(StateInspector, {
2235
1729
  store: activeStore,
2236
1730
  onApply: (id, next) => core.applyEdit(id, next)
2237
- }) : /* @__PURE__ */ jsx10(EmptyMessage, {
1731
+ }) : /* @__PURE__ */ jsx7(EmptyMessage, {
2238
1732
  children: "No stores registered. Call core.registerStore(...)."
2239
- }) : /* @__PURE__ */ jsxs8("div", {
1733
+ }) : /* @__PURE__ */ jsxs7("div", {
2240
1734
  style: {
2241
1735
  flex: 1,
2242
1736
  display: "flex",
@@ -2245,7 +1739,7 @@ function NiceStateDevtools_Panel({
2245
1739
  minHeight: 0
2246
1740
  },
2247
1741
  children: [
2248
- /* @__PURE__ */ jsxs8("div", {
1742
+ /* @__PURE__ */ jsxs7("div", {
2249
1743
  style: {
2250
1744
  flexGrow: selectedChange != null ? 1 - detailRatio : 1,
2251
1745
  flexShrink: 1,
@@ -2257,7 +1751,8 @@ function NiceStateDevtools_Panel({
2257
1751
  overflow: "hidden"
2258
1752
  },
2259
1753
  children: [
2260
- /* @__PURE__ */ jsx10(TimelineFollowToggles, {
1754
+ /* @__PURE__ */ jsx7(FollowLatestToggles, {
1755
+ noun: "change",
2261
1756
  stayOnLatest,
2262
1757
  onStayOnLatestChange: (next) => setPrefs({ stayOnLatest: next }),
2263
1758
  followLatestOnSelect,
@@ -2269,9 +1764,10 @@ function NiceStateDevtools_Panel({
2269
1764
  }
2270
1765
  }
2271
1766
  }),
2272
- /* @__PURE__ */ jsx10("div", {
2273
- style: { flex: 1, minHeight: 0, overflowY: "auto" },
2274
- children: /* @__PURE__ */ jsx10(ChangeList, {
1767
+ /* @__PURE__ */ jsx7("div", {
1768
+ style: { flex: 1, minHeight: 0, display: "flex", flexDirection: "column" },
1769
+ children: /* @__PURE__ */ jsx7(ChangeList, {
1770
+ style: { flex: 1, minHeight: 0, overflowY: "auto" },
2275
1771
  groups,
2276
1772
  selectedCuid: selectedChangeCuid,
2277
1773
  onSelect: (cuid) => {
@@ -2289,13 +1785,13 @@ function NiceStateDevtools_Panel({
2289
1785
  })
2290
1786
  ]
2291
1787
  }),
2292
- selectedChange != null && /* @__PURE__ */ jsxs8(Fragment, {
1788
+ selectedChange != null && /* @__PURE__ */ jsxs7(Fragment, {
2293
1789
  children: [
2294
- /* @__PURE__ */ jsx10(SplitHandle, {
1790
+ /* @__PURE__ */ jsx7(SplitHandle, {
2295
1791
  horizontal: isHorizDock,
2296
1792
  onRatioChange: (ratio) => setPrefs({ detailRatio: ratio })
2297
1793
  }),
2298
- /* @__PURE__ */ jsx10("div", {
1794
+ /* @__PURE__ */ jsx7("div", {
2299
1795
  style: {
2300
1796
  flexGrow: detailRatio,
2301
1797
  flexShrink: 1,
@@ -2313,7 +1809,7 @@ function NiceStateDevtools_Panel({
2313
1809
  boxShadow: "inset 0 18px 36px -14px rgba(0,0,0,0.8)"
2314
1810
  }
2315
1811
  },
2316
- children: /* @__PURE__ */ jsx10(ChangeDetailPanel, {
1812
+ children: /* @__PURE__ */ jsx7(ChangeDetailPanel, {
2317
1813
  change: selectedChange,
2318
1814
  onRevert: (c) => core.revertChange(c),
2319
1815
  view: detailView,
@@ -2331,84 +1827,8 @@ function NiceStateDevtools_Panel({
2331
1827
  ]
2332
1828
  });
2333
1829
  }
2334
- function TimelineFollowToggles({
2335
- stayOnLatest,
2336
- onStayOnLatestChange,
2337
- followLatestOnSelect,
2338
- onFollowLatestOnSelectChange
2339
- }) {
2340
- return /* @__PURE__ */ jsxs8("div", {
2341
- style: {
2342
- display: "flex",
2343
- flexDirection: "column",
2344
- flexShrink: 0,
2345
- paddingBottom: "3px",
2346
- background: DEVTOOL_SECTION_BACKGROUND,
2347
- borderBottom: `1px solid ${DEVTOOL_LIST_BASE_BACKGROUND}`
2348
- },
2349
- children: [
2350
- /* @__PURE__ */ jsx10(ToggleLabel, {
2351
- title: "Auto-select the most recent change so the detail pane keeps showing the latest as new changes land",
2352
- checked: stayOnLatest,
2353
- onChange: onStayOnLatestChange,
2354
- children: "Follow latest"
2355
- }),
2356
- /* @__PURE__ */ jsxs8("div", {
2357
- style: { display: "flex", alignItems: "center", paddingLeft: "12px", marginTop: "-4px" },
2358
- children: [
2359
- /* @__PURE__ */ jsx10("span", {
2360
- "aria-hidden": true,
2361
- style: {
2362
- color: DEVTOOL_COLOR_TEXT_MUTED,
2363
- fontFamily: SANS_FONT,
2364
- fontSize: "10px",
2365
- lineHeight: 1
2366
- },
2367
- children: "└"
2368
- }),
2369
- /* @__PURE__ */ jsx10(ToggleLabel, {
2370
- title: "When you click the latest change, turn 'Follow latest' back on so the view resumes tracking new changes. Turn this off to pin exactly to the change you click instead.",
2371
- checked: followLatestOnSelect,
2372
- onChange: onFollowLatestOnSelectChange,
2373
- children: "clicking latest re-follows"
2374
- })
2375
- ]
2376
- })
2377
- ]
2378
- });
2379
- }
2380
- function ToggleLabel({
2381
- checked,
2382
- onChange,
2383
- title,
2384
- children
2385
- }) {
2386
- return /* @__PURE__ */ jsxs8("label", {
2387
- title,
2388
- style: {
2389
- display: "flex",
2390
- alignItems: "center",
2391
- gap: "6px",
2392
- padding: "5px 10px",
2393
- cursor: "pointer",
2394
- userSelect: "none",
2395
- color: checked ? DEVTOOL_COLOR_TEXT_SECONDARY : DEVTOOL_COLOR_TEXT_MUTED,
2396
- fontSize: "10px",
2397
- fontFamily: SANS_FONT
2398
- },
2399
- children: [
2400
- /* @__PURE__ */ jsx10("input", {
2401
- type: "checkbox",
2402
- checked,
2403
- onChange: (e) => onChange(e.target.checked),
2404
- style: { accentColor: DEVTOOL_COLOR_SEMANTIC_SYSTEM, cursor: "pointer", margin: 0 }
2405
- }),
2406
- children
2407
- ]
2408
- });
2409
- }
2410
1830
  function EmptyMessage({ children }) {
2411
- return /* @__PURE__ */ jsx10("div", {
1831
+ return /* @__PURE__ */ jsx7("div", {
2412
1832
  style: {
2413
1833
  flex: 1,
2414
1834
  display: "flex",