react-state-inspector-devtools 1.0.3 → 1.1.2

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
@@ -221,7 +221,7 @@ function useComponentLabel(label) {
221
221
  }
222
222
 
223
223
  // src/StateInspectorUI.tsx
224
- var import_react4 = require("react");
224
+ var import_react5 = require("react");
225
225
  var import_react_dom = require("react-dom");
226
226
 
227
227
  // src/ui/constants.ts
@@ -280,38 +280,73 @@ function safeStringify(v) {
280
280
  }
281
281
  }
282
282
 
283
- // src/ui/components/FloatingButton.tsx
283
+ // src/ui/icons/DevtoolsIcon.tsx
284
284
  var import_jsx_runtime2 = require("react/jsx-runtime");
285
- function FloatingButton({ onClick }) {
286
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
285
+ var DevtoolsIcon = (props) => {
286
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
287
+ "svg",
288
+ {
289
+ width: "12",
290
+ height: "12",
291
+ viewBox: "0 0 12 12",
292
+ fill: "none",
293
+ xmlns: "http://www.w3.org/2000/svg",
294
+ ...props,
295
+ children: [
296
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("g", { clipPath: "url(#clip0_1_13)", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
297
+ "path",
298
+ {
299
+ d: "M2 7.00002C1.90538 7.00034 1.81262 6.97381 1.73248 6.92351C1.65234 6.87321 1.58812 6.8012 1.54727 6.71585C1.50643 6.6305 1.49065 6.53531 1.50175 6.44135C1.51285 6.34739 1.55039 6.2585 1.61 6.18502L6.56 1.08502C6.59713 1.04216 6.64773 1.0132 6.70349 1.00289C6.75925 0.992575 6.81686 1.00153 6.86687 1.02827C6.91687 1.05502 6.95629 1.09797 6.97867 1.15007C7.00104 1.20218 7.00504 1.26034 6.99 1.31502L6.03 4.32502C6.00169 4.40078 5.99219 4.48228 6.0023 4.56252C6.01241 4.64277 6.04183 4.71936 6.08805 4.78573C6.13426 4.85211 6.19589 4.90628 6.26764 4.9436C6.33939 4.98092 6.41912 5.00028 6.5 5.00002H10C10.0946 4.9997 10.1874 5.02623 10.2675 5.07653C10.3477 5.12683 10.4119 5.19884 10.4527 5.28419C10.4936 5.36954 10.5094 5.46473 10.4983 5.55869C10.4871 5.65266 10.4496 5.74154 10.39 5.81502L5.44 10.915C5.40287 10.9579 5.35227 10.9868 5.29651 10.9972C5.24075 11.0075 5.18314 10.9985 5.13313 10.9718C5.08313 10.945 5.04371 10.9021 5.02133 10.85C4.99896 10.7979 4.99496 10.7397 5.01 10.685L5.97 7.67502C5.99831 7.59926 6.00781 7.51776 5.9977 7.43752C5.98759 7.35727 5.95817 7.28068 5.91195 7.21431C5.86574 7.14793 5.80411 7.09376 5.73236 7.05644C5.66061 7.01912 5.58088 6.99976 5.5 7.00002H2Z",
300
+ fill: "inherit",
301
+ stroke: "inherit",
302
+ strokeLinecap: "round",
303
+ strokeLinejoin: "round"
304
+ }
305
+ ) }),
306
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("clipPath", { id: "clip0_1_13", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { width: "12", height: "12", fill: "white" }) }) })
307
+ ]
308
+ }
309
+ );
310
+ };
311
+ var DevtoolsIcon_default = DevtoolsIcon;
312
+
313
+ // src/ui/components/FloatingButton.tsx
314
+ var import_jsx_runtime3 = require("react/jsx-runtime");
315
+ function FloatingButton({ onClick, isActive }) {
316
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
287
317
  "button",
288
318
  {
319
+ "data-rsi-floating-button": true,
289
320
  title: "State Inspector (\u2318\u21E7I / Ctrl\u21E7I)",
290
321
  onClick,
291
322
  style: {
292
323
  position: "fixed",
293
324
  right: 16,
294
325
  bottom: 16,
295
- width: 44,
296
- height: 44,
297
- borderRadius: 22,
326
+ width: 48,
327
+ height: 48,
328
+ borderRadius: 24,
298
329
  border: "none",
299
- background: "#111",
330
+ background: isActive ? "#155DFC" : "#111",
300
331
  color: "#fff",
301
332
  cursor: "pointer",
302
- zIndex: 999999
333
+ zIndex: 999999,
334
+ padding: 0,
335
+ display: "flex",
336
+ alignItems: "center",
337
+ justifyContent: "center"
303
338
  },
304
339
  "aria-label": "Toggle State Inspector",
305
- children: "\u25CE"
340
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DevtoolsIcon_default, { fill: isActive ? "#FFF" : void 0, stroke: "#FFF", height: 20, width: 20 })
306
341
  }
307
342
  );
308
343
  }
309
344
 
310
345
  // src/ui/components/DockPreviewOverlay.tsx
311
- var import_jsx_runtime3 = require("react/jsx-runtime");
346
+ var import_jsx_runtime4 = require("react/jsx-runtime");
312
347
  function DockPreviewOverlay({ preview }) {
313
348
  if (!preview) return null;
314
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
349
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
315
350
  "div",
316
351
  {
317
352
  style: {
@@ -320,26 +355,66 @@ function DockPreviewOverlay({ preview }) {
320
355
  pointerEvents: "none",
321
356
  zIndex: 999998
322
357
  },
323
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: previewRectStyle(preview) })
358
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: previewRectStyle(preview) })
324
359
  }
325
360
  );
326
361
  }
327
362
 
328
363
  // src/ui/components/ResizeHandle.tsx
329
- var import_jsx_runtime4 = require("react/jsx-runtime");
330
- function ResizeHandle({ onResize }) {
331
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
364
+ var import_jsx_runtime5 = require("react/jsx-runtime");
365
+ var EDGE_SIZE = 6;
366
+ var CORNER_SIZE = 12;
367
+ var handleConfigs = {
368
+ // Edges
369
+ top: { top: 0, left: CORNER_SIZE, right: CORNER_SIZE, height: EDGE_SIZE, cursor: "ns-resize" },
370
+ bottom: {
371
+ bottom: 0,
372
+ left: CORNER_SIZE,
373
+ right: CORNER_SIZE,
374
+ height: EDGE_SIZE,
375
+ cursor: "ns-resize"
376
+ },
377
+ left: { left: 0, top: CORNER_SIZE, bottom: CORNER_SIZE, width: EDGE_SIZE, cursor: "ew-resize" },
378
+ right: { right: 0, top: CORNER_SIZE, bottom: CORNER_SIZE, width: EDGE_SIZE, cursor: "ew-resize" },
379
+ // Corners
380
+ "top-left": { top: 0, left: 0, width: CORNER_SIZE, height: CORNER_SIZE, cursor: "nwse-resize" },
381
+ "top-right": { top: 0, right: 0, width: CORNER_SIZE, height: CORNER_SIZE, cursor: "nesw-resize" },
382
+ "bottom-left": {
383
+ bottom: 0,
384
+ left: 0,
385
+ width: CORNER_SIZE,
386
+ height: CORNER_SIZE,
387
+ cursor: "nesw-resize"
388
+ },
389
+ "bottom-right": {
390
+ bottom: 0,
391
+ right: 0,
392
+ width: CORNER_SIZE,
393
+ height: CORNER_SIZE,
394
+ cursor: "nwse-resize"
395
+ }
396
+ };
397
+ function Handle({
398
+ direction,
399
+ onResize
400
+ }) {
401
+ const config = handleConfigs[direction];
402
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
332
403
  "div",
333
404
  {
334
405
  onPointerDown: (e) => {
406
+ e.stopPropagation();
335
407
  const startX = e.clientX;
336
408
  const startY = e.clientY;
337
409
  e.currentTarget.setPointerCapture(e.pointerId);
338
410
  const onMove = (ev) => {
339
- onResize({
340
- dx: ev.clientX - startX,
341
- dy: ev.clientY - startY
342
- });
411
+ onResize(
412
+ {
413
+ dx: ev.clientX - startX,
414
+ dy: ev.clientY - startY
415
+ },
416
+ direction
417
+ );
343
418
  };
344
419
  const onUp = () => {
345
420
  window.removeEventListener("pointermove", onMove);
@@ -350,24 +425,38 @@ function ResizeHandle({ onResize }) {
350
425
  },
351
426
  style: {
352
427
  position: "absolute",
353
- right: 6,
354
- bottom: 6,
355
- width: 14,
356
- height: 14,
357
- borderRadius: 6,
358
- border: "1px solid #333",
359
- background: "#838383",
360
- cursor: "nwse-resize"
428
+ top: config.top,
429
+ right: config.right,
430
+ bottom: config.bottom,
431
+ left: config.left,
432
+ width: config.width,
433
+ height: config.height,
434
+ cursor: config.cursor,
435
+ background: "transparent",
436
+ zIndex: 10
361
437
  }
362
438
  }
363
439
  );
364
440
  }
441
+ var directions = [
442
+ "top",
443
+ "right",
444
+ "bottom",
445
+ "left",
446
+ "top-left",
447
+ "top-right",
448
+ "bottom-left",
449
+ "bottom-right"
450
+ ];
451
+ function ResizeHandle({ onResize }) {
452
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: directions.map((dir) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Handle, { direction: dir, onResize }, dir)) });
453
+ }
365
454
 
366
455
  // src/ui/components/SidebarResizer.tsx
367
- var import_jsx_runtime5 = require("react/jsx-runtime");
456
+ var import_jsx_runtime6 = require("react/jsx-runtime");
368
457
  function SidebarResizer({ leftWidth, onWidthChange, hidden }) {
369
458
  if (hidden) return null;
370
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
459
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
371
460
  "div",
372
461
  {
373
462
  onPointerDown: (e) => {
@@ -400,67 +489,131 @@ function SidebarResizer({ leftWidth, onWidthChange, hidden }) {
400
489
  }
401
490
 
402
491
  // src/ui/components/DragHandle.tsx
403
- var import_jsx_runtime6 = require("react/jsx-runtime");
492
+ var import_react3 = require("react");
493
+ var import_jsx_runtime7 = require("react/jsx-runtime");
404
494
  function DragHandle({ children, onDragStart, onDragEnd, style }) {
405
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
495
+ const [isDragging, setIsDragging] = (0, import_react3.useState)(false);
496
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
406
497
  "div",
407
498
  {
408
- style: { cursor: "grab", userSelect: "none", ...style },
409
- onPointerDown: onDragStart,
410
- onPointerUp: onDragEnd,
499
+ style: { cursor: isDragging ? "grabbing" : "grab", userSelect: "none", ...style },
500
+ onPointerDown: (e) => {
501
+ const target = e.target;
502
+ try {
503
+ if (target && typeof target.closest === "function" && target.closest('button, input, textarea, a, [role="button"], [data-no-drag]')) {
504
+ return;
505
+ }
506
+ } catch (e2) {
507
+ console.error(e2);
508
+ }
509
+ setIsDragging(true);
510
+ onDragStart(e);
511
+ },
512
+ onPointerUp: () => {
513
+ if (isDragging) {
514
+ setIsDragging(false);
515
+ onDragEnd();
516
+ }
517
+ },
411
518
  children
412
519
  }
413
520
  );
414
521
  }
415
522
 
523
+ // src/ui/styles.ts
524
+ var inputStyle = {
525
+ padding: "8px 10px",
526
+ borderRadius: 4,
527
+ border: "none",
528
+ background: "#18181B",
529
+ color: "#fff",
530
+ minWidth: 120
531
+ };
532
+ var cardStyle = {
533
+ border: "1px solid rgba(39, 39, 42, 0.30)",
534
+ borderRadius: 12,
535
+ padding: 10
536
+ };
537
+
538
+ // src/ui/components/SearchInput.tsx
539
+ var import_jsx_runtime8 = require("react/jsx-runtime");
540
+ function SearchInput({ value, onChange, inputRef }) {
541
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
542
+ "input",
543
+ {
544
+ value,
545
+ onChange: (e) => onChange(e.target.value),
546
+ placeholder: "Filter\u2026",
547
+ ref: inputRef,
548
+ style: {
549
+ ...inputStyle,
550
+ outline: "none"
551
+ }
552
+ }
553
+ );
554
+ }
555
+
416
556
  // src/ui/components/ComponentList.tsx
417
- var import_jsx_runtime7 = require("react/jsx-runtime");
557
+ var import_jsx_runtime9 = require("react/jsx-runtime");
418
558
  function ComponentList({
419
559
  components,
420
560
  selectedId,
421
561
  onSelect,
422
- onDragStart,
423
- onDragEnd,
424
- height,
425
- hidden
562
+ hidden,
563
+ query,
564
+ onQueryChange,
565
+ searchRef
426
566
  }) {
427
567
  if (hidden) return null;
428
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { padding: 12, height, flexDirection: "column", boxSizing: "border-box", display: "flex" }, children: [
429
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
430
- DragHandle,
568
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { padding: 4, boxSizing: "border-box", backgroundColor: "#09090B" }, children: [
569
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
570
+ "div",
431
571
  {
432
- onDragStart,
433
- onDragEnd,
434
- style: { display: "flex", alignItems: "center", justifyContent: "space-between" },
435
- children: [
436
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h4", { style: { margin: 0 }, children: "Components" }),
437
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { fontSize: 12, opacity: 0.7 }, children: components.length })
438
- ]
572
+ style: {
573
+ display: "flex",
574
+ flexDirection: "column",
575
+ paddingTop: 4,
576
+ paddingBottom: 8,
577
+ paddingLeft: 4,
578
+ paddingRight: 4
579
+ },
580
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SearchInput, { value: query, onChange: onQueryChange, inputRef: searchRef })
439
581
  }
440
582
  ),
441
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { marginTop: 10, display: "flex", flexDirection: "column", gap: 8, overflow: "auto", flex: 1 }, children: components.map((c) => {
583
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 2, overflow: "auto", flex: 1 }, children: components.map((c) => {
442
584
  const active = c.id === selectedId;
443
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
585
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
444
586
  "button",
445
587
  {
446
588
  id: `rsi-comp-${c.id}`,
447
589
  onClick: () => onSelect(c.id),
448
590
  style: {
449
- textAlign: "left",
450
- background: active ? "#2a2a2a" : "transparent",
451
- border: "1px solid #333",
452
- borderRadius: 10,
453
- padding: 10,
454
- color: "#fff",
455
- cursor: "pointer",
456
- flex: "none"
591
+ display: "flex",
592
+ justifyContent: "space-between",
593
+ alignItems: "center",
594
+ padding: 8,
595
+ backgroundColor: active ? "#27272A" : "transparent",
596
+ border: "none"
457
597
  },
458
598
  children: [
459
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { fontWeight: 700 }, children: c.label }),
460
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { fontSize: 12, opacity: 0.7 }, children: [
461
- "states: ",
462
- c.stateKeys.length || 0
463
- ] })
599
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { fontWeight: 500, fontSize: 12, color: active ? "#fff" : "#9F9FA9" }, children: c.label }),
600
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
601
+ "div",
602
+ {
603
+ style: {
604
+ fontSize: 9,
605
+ height: 16,
606
+ width: 16,
607
+ color: "#D4D4D8",
608
+ display: "flex",
609
+ alignItems: "center",
610
+ justifyContent: "center",
611
+ borderRadius: 8,
612
+ backgroundColor: "#3F3F47"
613
+ },
614
+ children: c.stateKeys.length
615
+ }
616
+ )
464
617
  ]
465
618
  },
466
619
  c.id
@@ -470,17 +623,14 @@ function ComponentList({
470
623
  }
471
624
 
472
625
  // src/ui/components/StatePanelHeader.tsx
473
- var import_jsx_runtime8 = require("react/jsx-runtime");
626
+ var import_jsx_runtime10 = require("react/jsx-runtime");
474
627
  function StatePanelHeader({
475
628
  selectedLabel,
476
629
  leftCollapsed,
477
- onToggleCollapse,
478
- onClose,
479
- onDragStart,
480
- onDragEnd
630
+ onToggleCollapse
481
631
  }) {
482
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex", alignItems: "center" }, children: [
483
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
632
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { display: "flex", alignItems: "center" }, children: [
633
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
484
634
  "button",
485
635
  {
486
636
  onClick: (e) => {
@@ -502,78 +652,17 @@ function StatePanelHeader({
502
652
  children: leftCollapsed ? "\xBB" : "\xAB"
503
653
  }
504
654
  ),
505
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
506
- DragHandle,
507
- {
508
- onDragStart,
509
- onDragEnd,
510
- style: { display: "flex", flexDirection: "column", flex: 1 },
511
- children: [
512
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h4", { style: { margin: 0 }, children: "State" }),
513
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { fontSize: 12, opacity: 0.7 }, children: selectedLabel ?? "No selection" })
514
- ]
515
- }
516
- ),
517
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
518
- "button",
519
- {
520
- onClick: onClose,
521
- style: {
522
- background: "transparent",
523
- color: "#fff",
524
- border: "1px solid #333",
525
- borderRadius: 10,
526
- padding: "6px 10px",
527
- cursor: "pointer",
528
- fontSize: 12,
529
- marginLeft: "auto"
530
- },
531
- children: "Close"
532
- }
533
- )
655
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h4", { style: { margin: 0 }, children: selectedLabel ?? "No selection" })
534
656
  ] });
535
657
  }
536
658
 
537
- // src/ui/styles.ts
538
- var inputStyle = {
539
- padding: "8px 10px",
540
- borderRadius: 10,
541
- border: "1px solid #333",
542
- background: "#111",
543
- color: "#fff"
544
- };
545
- var cardStyle = {
546
- border: "1px solid #333",
547
- borderRadius: 12,
548
- padding: 10
549
- };
550
-
551
- // src/ui/components/SearchInput.tsx
552
- var import_jsx_runtime9 = require("react/jsx-runtime");
553
- function SearchInput({ value, onChange, inputRef }) {
554
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
555
- "input",
556
- {
557
- value,
558
- onChange: (e) => onChange(e.target.value),
559
- placeholder: "Search components / state keys\u2026",
560
- ref: inputRef,
561
- style: {
562
- ...inputStyle,
563
- marginTop: 10,
564
- outline: "none"
565
- }
566
- }
567
- );
568
- }
569
-
570
659
  // src/ui/components/JsonEditor.tsx
571
- var import_react3 = require("react");
572
- var import_jsx_runtime10 = require("react/jsx-runtime");
660
+ var import_react4 = require("react");
661
+ var import_jsx_runtime11 = require("react/jsx-runtime");
573
662
  function JsonEditor({ initial, onValidJson }) {
574
- const [raw, setRaw] = (0, import_react3.useState)(initial);
575
- const [error, setError] = (0, import_react3.useState)(null);
576
- (0, import_react3.useEffect)(() => {
663
+ const [raw, setRaw] = (0, import_react4.useState)(initial);
664
+ const [error, setError] = (0, import_react4.useState)(null);
665
+ (0, import_react4.useEffect)(() => {
577
666
  setRaw(initial);
578
667
  }, [initial]);
579
668
  const handleChange = (e) => {
@@ -587,8 +676,8 @@ function JsonEditor({ initial, onValidJson }) {
587
676
  setError("Invalid JSON");
588
677
  }
589
678
  };
590
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { display: "grid", gap: 6 }, children: [
591
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
679
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: { display: "grid", gap: 6 }, children: [
680
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
592
681
  "textarea",
593
682
  {
594
683
  value: raw,
@@ -602,16 +691,16 @@ function JsonEditor({ initial, onValidJson }) {
602
691
  }
603
692
  }
604
693
  ),
605
- error && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { fontSize: 12, color: "#ff6b6b" }, children: error })
694
+ error && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: { fontSize: 12, color: "#ff6b6b" }, children: error })
606
695
  ] });
607
696
  }
608
697
 
609
698
  // src/ui/components/StateEditor.tsx
610
- var import_jsx_runtime11 = require("react/jsx-runtime");
699
+ var import_jsx_runtime12 = require("react/jsx-runtime");
611
700
  function StateEditor({ value, meta, onChange }) {
612
701
  if (meta?.type === "boolean" || typeof value === "boolean") {
613
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { style: { display: "flex", gap: 10, alignItems: "center" }, children: [
614
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
702
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { style: { display: "flex", gap: 10, alignItems: "center" }, children: [
703
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
615
704
  "input",
616
705
  {
617
706
  type: "checkbox",
@@ -619,26 +708,29 @@ function StateEditor({ value, meta, onChange }) {
619
708
  onChange: (e) => onChange(e.target.checked)
620
709
  }
621
710
  ),
622
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { style: { fontSize: 13, opacity: 0.8 }, children: String(Boolean(value)) })
711
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: { fontSize: 13, opacity: 0.8 }, children: String(Boolean(value)) })
623
712
  ] });
624
713
  }
625
714
  if (meta?.type === "select" && Array.isArray(meta.options)) {
626
715
  const current = typeof value === "string" ? value : String(value ?? "");
627
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
716
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
628
717
  "select",
629
718
  {
630
719
  value: current,
631
720
  onChange: (e) => onChange(e.target.value),
632
- style: inputStyle,
721
+ style: {
722
+ ...inputStyle,
723
+ minWidth: 120
724
+ },
633
725
  children: meta.options.map((opt) => {
634
726
  const o = isOptionObject(opt) ? opt : { label: String(opt), value: String(opt) };
635
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: o.value, children: o.label }, o.value);
727
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: o.value, children: o.label }, o.value);
636
728
  })
637
729
  }
638
730
  );
639
731
  }
640
732
  if (meta?.type === "number") {
641
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
733
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
642
734
  "input",
643
735
  {
644
736
  type: "number",
@@ -652,9 +744,9 @@ function StateEditor({ value, meta, onChange }) {
652
744
  );
653
745
  }
654
746
  if (meta?.type === "json" || value && typeof value === "object") {
655
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(JsonEditor, { initial: safeStringify(value), onValidJson: onChange });
747
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(JsonEditor, { initial: safeStringify(value), onValidJson: onChange });
656
748
  }
657
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
749
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
658
750
  "input",
659
751
  {
660
752
  type: "text",
@@ -667,23 +759,35 @@ function StateEditor({ value, meta, onChange }) {
667
759
  }
668
760
 
669
761
  // src/ui/components/StateCard.tsx
670
- var import_jsx_runtime12 = require("react/jsx-runtime");
762
+ var import_jsx_runtime13 = require("react/jsx-runtime");
671
763
  function StateCard({ state }) {
672
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
764
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
673
765
  "div",
674
766
  {
675
767
  style: {
676
768
  ...cardStyle,
677
769
  display: "flex",
678
- flexDirection: "column",
770
+ flexDirection: "row",
771
+ justifyContent: "space-between",
679
772
  gap: 8
680
773
  },
681
774
  children: [
682
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { style: { display: "flex", justifyContent: "space-between", gap: 12 }, children: [
683
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { style: { fontWeight: 700 }, children: state.key }),
684
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { style: { fontSize: 12, opacity: 0.6 }, children: state.meta?.type ?? "auto" })
685
- ] }),
686
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
775
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
776
+ "div",
777
+ {
778
+ style: {
779
+ display: "flex",
780
+ flexDirection: "column",
781
+ justifyContent: "space-between",
782
+ gap: 1
783
+ },
784
+ children: [
785
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { fontSize: 14 }, children: state.key }),
786
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { fontSize: 12, color: "#52525C", textTransform: "uppercase" }, children: state.meta?.type ?? "auto" })
787
+ ]
788
+ }
789
+ ),
790
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
687
791
  StateEditor,
688
792
  {
689
793
  value: state.value,
@@ -697,60 +801,258 @@ function StateCard({ state }) {
697
801
  }
698
802
 
699
803
  // src/ui/components/StateEditorPanel.tsx
700
- var import_jsx_runtime13 = require("react/jsx-runtime");
804
+ var import_jsx_runtime14 = require("react/jsx-runtime");
701
805
  function StateEditorPanel({
702
806
  selected,
703
- query,
704
- onQueryChange,
705
- searchRef,
706
807
  leftCollapsed,
707
- onToggleCollapse,
708
- onClose,
709
- onDragStart,
710
- onDragEnd
808
+ onToggleCollapse
711
809
  }) {
712
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { padding: 12, overflow: "auto", display: "flex", flexDirection: "column", boxSizing: "border-box" }, children: [
713
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
714
- StatePanelHeader,
715
- {
716
- selectedLabel: selected?.label ?? null,
717
- leftCollapsed,
718
- onToggleCollapse,
719
- onClose,
720
- onDragStart,
721
- onDragEnd
722
- }
723
- ),
724
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
725
- SearchInput,
726
- {
727
- value: query,
728
- onChange: onQueryChange,
729
- inputRef: searchRef
730
- }
731
- ),
732
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { marginTop: 12, display: "grid", gap: 10 }, children: [
733
- selected && selected.states.size === 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { fontSize: 13, opacity: 0.7 }, children: "This component has no inspectable state." }),
734
- !selected && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { opacity: 0.7, fontSize: 13 }, children: "No component selected." }),
735
- selected && Array.from(selected.states.values()).map((s) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(StateCard, { state: s }, s.key))
736
- ] })
737
- ] });
810
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
811
+ "div",
812
+ {
813
+ style: {
814
+ padding: 12,
815
+ overflow: "auto",
816
+ display: "flex",
817
+ flexDirection: "column",
818
+ boxSizing: "border-box",
819
+ backgroundColor: "#0C0C0E"
820
+ },
821
+ children: [
822
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
823
+ StatePanelHeader,
824
+ {
825
+ selectedLabel: selected?.label ?? null,
826
+ leftCollapsed,
827
+ onToggleCollapse
828
+ }
829
+ ),
830
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { marginTop: 12, display: "grid", gap: 10 }, children: [
831
+ selected && selected.states.size === 0 && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { fontSize: 13, opacity: 0.7 }, children: "This component has no inspectable state." }),
832
+ !selected && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { opacity: 0.7, fontSize: 13 }, children: "No component selected." }),
833
+ selected && Array.from(selected.states.values()).map((s) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(StateCard, { state: s }, s.key))
834
+ ] })
835
+ ]
836
+ }
837
+ );
738
838
  }
739
839
 
840
+ // src/ui/icons/DragIcon.tsx
841
+ var import_jsx_runtime15 = require("react/jsx-runtime");
842
+ var DragIcon = (props) => {
843
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
844
+ "svg",
845
+ {
846
+ width: "16",
847
+ height: "16",
848
+ viewBox: "0 0 16 16",
849
+ fill: "none",
850
+ xmlns: "http://www.w3.org/2000/svg",
851
+ ...props,
852
+ children: [
853
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
854
+ "path",
855
+ {
856
+ d: "M7.99998 6.66665C8.36817 6.66665 8.66665 6.36817 8.66665 5.99998C8.66665 5.63179 8.36817 5.33331 7.99998 5.33331C7.63179 5.33331 7.33331 5.63179 7.33331 5.99998C7.33331 6.36817 7.63179 6.66665 7.99998 6.66665Z",
857
+ stroke: "#3F3F46",
858
+ strokeWidth: 1.33333,
859
+ strokeLinecap: "round",
860
+ strokeLinejoin: "round"
861
+ }
862
+ ),
863
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
864
+ "path",
865
+ {
866
+ d: "M12.6667 6.66665C13.0349 6.66665 13.3333 6.36817 13.3333 5.99998C13.3333 5.63179 13.0349 5.33331 12.6667 5.33331C12.2985 5.33331 12 5.63179 12 5.99998C12 6.36817 12.2985 6.66665 12.6667 6.66665Z",
867
+ stroke: "#3F3F46",
868
+ strokeWidth: 1.33333,
869
+ strokeLinecap: "round",
870
+ strokeLinejoin: "round"
871
+ }
872
+ ),
873
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
874
+ "path",
875
+ {
876
+ d: "M3.33335 6.66665C3.70154 6.66665 4.00002 6.36817 4.00002 5.99998C4.00002 5.63179 3.70154 5.33331 3.33335 5.33331C2.96516 5.33331 2.66669 5.63179 2.66669 5.99998C2.66669 6.36817 2.96516 6.66665 3.33335 6.66665Z",
877
+ stroke: "#3F3F46",
878
+ strokeWidth: 1.33333,
879
+ strokeLinecap: "round",
880
+ strokeLinejoin: "round"
881
+ }
882
+ ),
883
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
884
+ "path",
885
+ {
886
+ d: "M7.99998 10.6666C8.36817 10.6666 8.66665 10.3682 8.66665 9.99998C8.66665 9.63179 8.36817 9.33331 7.99998 9.33331C7.63179 9.33331 7.33331 9.63179 7.33331 9.99998C7.33331 10.3682 7.63179 10.6666 7.99998 10.6666Z",
887
+ stroke: "#3F3F46",
888
+ strokeWidth: 1.33333,
889
+ strokeLinecap: "round",
890
+ strokeLinejoin: "round"
891
+ }
892
+ ),
893
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
894
+ "path",
895
+ {
896
+ d: "M12.6667 10.6666C13.0349 10.6666 13.3333 10.3682 13.3333 9.99998C13.3333 9.63179 13.0349 9.33331 12.6667 9.33331C12.2985 9.33331 12 9.63179 12 9.99998C12 10.3682 12.2985 10.6666 12.6667 10.6666Z",
897
+ stroke: "#3F3F46",
898
+ strokeWidth: 1.33333,
899
+ strokeLinecap: "round",
900
+ strokeLinejoin: "round"
901
+ }
902
+ ),
903
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
904
+ "path",
905
+ {
906
+ d: "M3.33335 10.6666C3.70154 10.6666 4.00002 10.3682 4.00002 9.99998C4.00002 9.63179 3.70154 9.33331 3.33335 9.33331C2.96516 9.33331 2.66669 9.63179 2.66669 9.99998C2.66669 10.3682 2.96516 10.6666 3.33335 10.6666Z",
907
+ stroke: "#3F3F46",
908
+ strokeWidth: 1.33333,
909
+ strokeLinecap: "round",
910
+ strokeLinejoin: "round"
911
+ }
912
+ )
913
+ ]
914
+ }
915
+ );
916
+ };
917
+ var DragIcon_default = DragIcon;
918
+
919
+ // src/ui/icons/CloseIcon.tsx
920
+ var import_jsx_runtime16 = require("react/jsx-runtime");
921
+ var CloseIcon = (props) => {
922
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
923
+ "svg",
924
+ {
925
+ width: "14",
926
+ height: "14",
927
+ viewBox: "0 0 14 14",
928
+ fill: "none",
929
+ xmlns: "http://www.w3.org/2000/svg",
930
+ ...props,
931
+ children: [
932
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
933
+ "path",
934
+ {
935
+ d: "M10.5 3.5L3.5 10.5",
936
+ stroke: "#71717B",
937
+ strokeWidth: 1.16667,
938
+ strokeLinecap: "round",
939
+ strokeLinejoin: "round"
940
+ }
941
+ ),
942
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
943
+ "path",
944
+ {
945
+ d: "M3.5 3.5L10.5 10.5",
946
+ stroke: "#71717B",
947
+ strokeWidth: 1.16667,
948
+ strokeLinecap: "round",
949
+ strokeLinejoin: "round"
950
+ }
951
+ )
952
+ ]
953
+ }
954
+ );
955
+ };
956
+ var CloseIcon_default = CloseIcon;
957
+
958
+ // src/ui/components/DockHeader.tsx
959
+ var import_jsx_runtime17 = require("react/jsx-runtime");
960
+ var DockHeader = ({ setOpen, handleDragStart, handleDragEnd }) => {
961
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DragHandle, { onDragStart: handleDragStart, onDragEnd: handleDragEnd, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
962
+ "div",
963
+ {
964
+ style: {
965
+ height: 40,
966
+ width: "100%",
967
+ padding: "9.5px 12px",
968
+ boxSizing: "border-box",
969
+ borderBottom: "1px solid rgba(39, 39, 42, 0.5)",
970
+ display: "flex",
971
+ flexDirection: "row",
972
+ backgroundColor: "rgba(24, 24, 27, 0.5)"
973
+ },
974
+ children: [
975
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
976
+ "div",
977
+ {
978
+ style: {
979
+ width: 20,
980
+ height: 20,
981
+ display: "flex",
982
+ alignItems: "center",
983
+ justifyContent: "center",
984
+ marginRight: 8,
985
+ backgroundColor: "#27272A",
986
+ borderRadius: 4
987
+ },
988
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DevtoolsIcon_default, { fill: "#9F9FA9", stroke: "#9F9FA9", height: 12, width: 12 })
989
+ }
990
+ ),
991
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
992
+ "span",
993
+ {
994
+ style: {
995
+ fontSize: 12,
996
+ fontWeight: 500,
997
+ color: "#E4E4E7"
998
+ },
999
+ children: "React Inspector"
1000
+ }
1001
+ ),
1002
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1003
+ "div",
1004
+ {
1005
+ style: {
1006
+ marginLeft: "auto",
1007
+ display: "flex",
1008
+ flexDirection: "row",
1009
+ gap: 16,
1010
+ alignItems: "center"
1011
+ },
1012
+ children: [
1013
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DragIcon_default, {}),
1014
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1015
+ "div",
1016
+ {
1017
+ "data-no-drag": true,
1018
+ style: {
1019
+ cursor: "pointer",
1020
+ width: 20,
1021
+ height: 20,
1022
+ display: "flex",
1023
+ alignItems: "center",
1024
+ justifyContent: "center"
1025
+ },
1026
+ onClick: (e) => {
1027
+ e.stopPropagation();
1028
+ setOpen(false);
1029
+ },
1030
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(CloseIcon_default, {})
1031
+ }
1032
+ )
1033
+ ]
1034
+ }
1035
+ )
1036
+ ]
1037
+ }
1038
+ ) });
1039
+ };
1040
+ var DockHeader_default = DockHeader;
1041
+
740
1042
  // src/StateInspectorUI.tsx
741
- var import_jsx_runtime14 = require("react/jsx-runtime");
1043
+ var import_jsx_runtime18 = require("react/jsx-runtime");
742
1044
  function StateInspectorUI() {
743
1045
  const store = useInspectorStore();
744
- const [query, setQuery] = (0, import_react4.useState)("");
745
- const [leftCollapsed, setLeftCollapsed] = (0, import_react4.useState)(false);
746
- const [layout, setLayout] = (0, import_react4.useState)("floating");
747
- const [preview, setPreview] = (0, import_react4.useState)(null);
748
- const [isTransitioning, setIsTransitioning] = (0, import_react4.useState)(false);
749
- const [open, setOpen] = (0, import_react4.useState)(false);
750
- const [selectedId, setSelectedId] = (0, import_react4.useState)(null);
751
- const [tick, force] = (0, import_react4.useState)(0);
752
- const searchRef = (0, import_react4.useRef)(null);
753
- const [pos, setPos] = (0, import_react4.useState)(() => {
1046
+ const [query, setQuery] = (0, import_react5.useState)("");
1047
+ const [leftCollapsed, setLeftCollapsed] = (0, import_react5.useState)(false);
1048
+ const [layout, setLayout] = (0, import_react5.useState)("floating");
1049
+ const [preview, setPreview] = (0, import_react5.useState)(null);
1050
+ const [isTransitioning, setIsTransitioning] = (0, import_react5.useState)(false);
1051
+ const [open, setOpen] = (0, import_react5.useState)(false);
1052
+ const [selectedId, setSelectedId] = (0, import_react5.useState)(null);
1053
+ const [tick, force] = (0, import_react5.useState)(0);
1054
+ const searchRef = (0, import_react5.useRef)(null);
1055
+ const [pos, setPos] = (0, import_react5.useState)(() => {
754
1056
  try {
755
1057
  const raw = localStorage.getItem(LS_KEY);
756
1058
  return raw ? JSON.parse(raw) : { right: 16, bottom: 72 };
@@ -758,7 +1060,7 @@ function StateInspectorUI() {
758
1060
  return { right: 16, bottom: 72 };
759
1061
  }
760
1062
  });
761
- const [leftWidth, setLeftWidth] = (0, import_react4.useState)(() => {
1063
+ const [leftWidth, setLeftWidth] = (0, import_react5.useState)(() => {
762
1064
  try {
763
1065
  const raw = localStorage.getItem(LS_LEFT_W);
764
1066
  return raw ? Number(raw) : 280;
@@ -766,7 +1068,7 @@ function StateInspectorUI() {
766
1068
  return 280;
767
1069
  }
768
1070
  });
769
- const [size, setSize] = (0, import_react4.useState)(() => {
1071
+ const [size, setSize] = (0, import_react5.useState)(() => {
770
1072
  try {
771
1073
  const raw = localStorage.getItem(LS_SIZE);
772
1074
  return raw ? JSON.parse(raw) : { width: 720, height: 420 };
@@ -774,49 +1076,46 @@ function StateInspectorUI() {
774
1076
  return { width: 720, height: 420 };
775
1077
  }
776
1078
  });
777
- (0, import_react4.useEffect)(() => {
1079
+ (0, import_react5.useEffect)(() => {
778
1080
  try {
779
1081
  localStorage.setItem(LS_LAYOUT, layout);
780
1082
  } catch (e) {
781
1083
  console.error(e);
782
1084
  }
783
1085
  }, [layout]);
784
- (0, import_react4.useEffect)(() => {
1086
+ (0, import_react5.useEffect)(() => {
785
1087
  try {
786
1088
  localStorage.setItem(LS_KEY, JSON.stringify(pos));
787
1089
  } catch (e) {
788
1090
  console.error(e);
789
1091
  }
790
1092
  }, [pos]);
791
- (0, import_react4.useEffect)(() => {
1093
+ (0, import_react5.useEffect)(() => {
792
1094
  try {
793
1095
  localStorage.setItem(LS_LEFT_W, String(leftWidth));
794
1096
  } catch (e) {
795
1097
  console.error(e);
796
1098
  }
797
1099
  }, [leftWidth]);
798
- (0, import_react4.useEffect)(() => {
1100
+ (0, import_react5.useEffect)(() => {
799
1101
  try {
800
1102
  localStorage.setItem(LS_SIZE, JSON.stringify(size));
801
1103
  } catch (e) {
802
1104
  console.error(e);
803
1105
  }
804
1106
  }, [size]);
805
- (0, import_react4.useEffect)(() => {
1107
+ (0, import_react5.useEffect)(() => {
806
1108
  const shouldCollapse = leftWidth <= 200 || (size.width ?? 720) - leftWidth < 320;
807
1109
  setLeftCollapsed(shouldCollapse);
808
1110
  }, [leftWidth, size.width]);
809
- console.log("Store", store);
810
- (0, import_react4.useEffect)(() => store.subscribe(() => force((x) => x + 1)), [store]);
811
- const snapshot = (0, import_react4.useMemo)(() => store.getSnapshot(), [store, tick]);
812
- console.log("Snapshot", snapshot);
813
- const components = (0, import_react4.useMemo)(
1111
+ (0, import_react5.useEffect)(() => store.subscribe(() => force((x) => x + 1)), [store]);
1112
+ const snapshot = (0, import_react5.useMemo)(() => store.getSnapshot(), [store, tick]);
1113
+ const components = (0, import_react5.useMemo)(
814
1114
  () => snapshot.components.filter((c) => c.mounted),
815
1115
  [snapshot.components]
816
1116
  );
817
- console.log(components);
818
1117
  const q = query.trim().toLowerCase();
819
- const filtered = (0, import_react4.useMemo)(
1118
+ const filtered = (0, import_react5.useMemo)(
820
1119
  () => q ? components.filter((c) => {
821
1120
  const labelHit = c.label.toLowerCase().includes(q);
822
1121
  const keyHit = c.stateKeys.some((k) => k.toLowerCase().includes(q));
@@ -824,8 +1123,7 @@ function StateInspectorUI() {
824
1123
  }) : components,
825
1124
  [q, components]
826
1125
  );
827
- console.log(filtered);
828
- (0, import_react4.useEffect)(() => {
1126
+ (0, import_react5.useEffect)(() => {
829
1127
  if (!open) return;
830
1128
  if (components.length === 0) {
831
1129
  setSelectedId(null);
@@ -835,7 +1133,7 @@ function StateInspectorUI() {
835
1133
  setSelectedId(components[0].id);
836
1134
  }
837
1135
  }, [open, components.length]);
838
- (0, import_react4.useEffect)(() => {
1136
+ (0, import_react5.useEffect)(() => {
839
1137
  function onKey(e) {
840
1138
  const mod = isMac ? e.metaKey : e.ctrlKey;
841
1139
  if (mod && e.shiftKey && e.key.toLowerCase() === "i") {
@@ -868,7 +1166,7 @@ function StateInspectorUI() {
868
1166
  window.addEventListener("keydown", onKey);
869
1167
  return () => window.removeEventListener("keydown", onKey);
870
1168
  }, [open, filtered, selectedId]);
871
- const selected = (0, import_react4.useMemo)(() => {
1169
+ const selected = (0, import_react5.useMemo)(() => {
872
1170
  if (!selectedId) return null;
873
1171
  return store.components.get(selectedId) ?? null;
874
1172
  }, [store, selectedId]);
@@ -924,20 +1222,56 @@ function StateInspectorUI() {
924
1222
  window.addEventListener("pointermove", onMove);
925
1223
  window.addEventListener("pointerup", onUp);
926
1224
  };
927
- const handlePanelResize = (startSize) => (delta) => {
928
- setSize({
929
- width: Math.min(window.innerWidth - 16, Math.max(480, (startSize.width ?? 0) + delta.dx)),
930
- height: Math.min(window.innerHeight - 120, Math.max(280, (startSize.height ?? 0) + delta.dy))
931
- });
1225
+ const handlePanelResize = (startSize, startPos) => (delta, direction) => {
1226
+ const isLeft = direction === "left" || direction.endsWith("left");
1227
+ const isTop = direction === "top" || direction.startsWith("top");
1228
+ const isHorizontal = direction !== "top" && direction !== "bottom";
1229
+ const isVertical = direction !== "left" && direction !== "right";
1230
+ const currentWidth = startSize.width ?? 720;
1231
+ const currentHeight = startSize.height ?? 420;
1232
+ let newWidth = currentWidth;
1233
+ let newHeight = currentHeight;
1234
+ if (isHorizontal) {
1235
+ if (isLeft) {
1236
+ newWidth = Math.min(window.innerWidth - 16, Math.max(480, currentWidth - delta.dx));
1237
+ } else {
1238
+ newWidth = Math.min(window.innerWidth - 16, Math.max(480, currentWidth + delta.dx));
1239
+ }
1240
+ }
1241
+ if (isVertical) {
1242
+ if (isTop) {
1243
+ newHeight = Math.min(window.innerHeight - 120, Math.max(280, currentHeight - delta.dy));
1244
+ } else {
1245
+ newHeight = Math.min(window.innerHeight - 120, Math.max(280, currentHeight + delta.dy));
1246
+ }
1247
+ }
1248
+ setSize({ width: newWidth, height: newHeight });
1249
+ const newPos = { ...startPos };
1250
+ if (isLeft && startPos.left !== void 0) {
1251
+ const widthDelta = newWidth - currentWidth;
1252
+ newPos.left = Math.max(8, startPos.left - widthDelta);
1253
+ } else if (isLeft && startPos.right !== void 0) {
1254
+ const widthDelta = newWidth - currentWidth;
1255
+ newPos.right = Math.max(8, startPos.right - widthDelta);
1256
+ }
1257
+ if (isTop && startPos.top !== void 0) {
1258
+ const heightDelta = newHeight - currentHeight;
1259
+ newPos.top = Math.max(8, startPos.top - heightDelta);
1260
+ } else if (isTop && startPos.bottom !== void 0) {
1261
+ const heightDelta = newHeight - currentHeight;
1262
+ newPos.bottom = Math.max(8, startPos.bottom - heightDelta);
1263
+ }
1264
+ setPos(newPos);
932
1265
  };
933
1266
  if (!store.enabled) return null;
934
1267
  return (0, import_react_dom.createPortal)(
935
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
936
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(FloatingButton, { onClick: () => setOpen((o) => !o) }),
937
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DockPreviewOverlay, { preview }),
938
- open && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1268
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
1269
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(FloatingButton, { onClick: () => setOpen((o) => !o), isActive: open }),
1270
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DockPreviewOverlay, { preview }),
1271
+ open && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
939
1272
  "div",
940
1273
  {
1274
+ "data-rsi-root": true,
941
1275
  style: {
942
1276
  position: "fixed",
943
1277
  left: pos.left,
@@ -953,45 +1287,59 @@ function StateInspectorUI() {
953
1287
  borderRadius: 12,
954
1288
  border: "1px solid #333",
955
1289
  zIndex: 999999,
956
- display: "grid",
957
- gridTemplateColumns: leftCollapsed ? "auto" : `${leftWidth}px 14px auto`,
958
1290
  overflow: "hidden",
959
- transition: isTransitioning ? "all 0.3s ease" : "none"
1291
+ transition: isTransitioning ? "all 0.3s ease" : "none",
1292
+ display: "flex",
1293
+ flexDirection: "column"
960
1294
  },
961
1295
  children: [
962
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ResizeHandle, { onResize: handlePanelResize(size) }),
963
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
964
- ComponentList,
965
- {
966
- components: filtered,
967
- selectedId,
968
- onSelect: setSelectedId,
969
- onDragStart: handleDragStart,
970
- onDragEnd: handleDragEnd,
971
- height: size.height,
972
- hidden: leftCollapsed
973
- }
974
- ),
975
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
976
- SidebarResizer,
1296
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1297
+ DockHeader_default,
977
1298
  {
978
- leftWidth,
979
- onWidthChange: setLeftWidth,
980
- hidden: leftCollapsed
1299
+ setOpen,
1300
+ handleDragStart,
1301
+ handleDragEnd
981
1302
  }
982
1303
  ),
983
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
984
- StateEditorPanel,
1304
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
1305
+ "div",
985
1306
  {
986
- selected,
987
- query,
988
- onQueryChange: setQuery,
989
- searchRef,
990
- leftCollapsed,
991
- onToggleCollapse: () => setLeftCollapsed((v) => !v),
992
- onClose: () => setOpen(false),
993
- onDragStart: handleDragStart,
994
- onDragEnd: handleDragEnd
1307
+ style: {
1308
+ display: "grid",
1309
+ gridTemplateColumns: leftCollapsed ? "auto" : `${leftWidth}px 14px auto`,
1310
+ height: "100%"
1311
+ },
1312
+ children: [
1313
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ResizeHandle, { onResize: handlePanelResize(size, pos) }),
1314
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1315
+ ComponentList,
1316
+ {
1317
+ query,
1318
+ onQueryChange: setQuery,
1319
+ searchRef,
1320
+ components: filtered,
1321
+ selectedId,
1322
+ onSelect: setSelectedId,
1323
+ hidden: leftCollapsed
1324
+ }
1325
+ ),
1326
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1327
+ SidebarResizer,
1328
+ {
1329
+ leftWidth,
1330
+ onWidthChange: setLeftWidth,
1331
+ hidden: leftCollapsed
1332
+ }
1333
+ ),
1334
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1335
+ StateEditorPanel,
1336
+ {
1337
+ selected,
1338
+ leftCollapsed,
1339
+ onToggleCollapse: () => setLeftCollapsed((v) => !v)
1340
+ }
1341
+ )
1342
+ ]
995
1343
  }
996
1344
  )
997
1345
  ]