react-state-inspector-devtools 1.0.3 → 1.1.1

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