@preact/signals-devtools-ui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/styles.css ADDED
@@ -0,0 +1,835 @@
1
+ /* DevTools Panel Styles */
2
+
3
+ * {
4
+ box-sizing: border-box;
5
+ margin: 0;
6
+ padding: 0;
7
+ }
8
+
9
+ body {
10
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
11
+ font-size: 13px;
12
+ line-height: 1.4;
13
+ color: #333;
14
+ background: #f5f5f5;
15
+ overflow: hidden;
16
+ }
17
+
18
+ #app {
19
+ height: 100vh;
20
+ display: flex;
21
+ flex-direction: column;
22
+ }
23
+
24
+ /* Header */
25
+ .header {
26
+ background: #fff;
27
+ border-bottom: 1px solid #e0e0e0;
28
+ padding: 8px 12px;
29
+ display: flex;
30
+ justify-content: space-between;
31
+ align-items: center;
32
+ flex-shrink: 0;
33
+ }
34
+
35
+ .header-title {
36
+ display: flex;
37
+ align-items: center;
38
+ gap: 12px;
39
+ }
40
+
41
+ .header-title h1 {
42
+ font-size: 16px;
43
+ font-weight: 700;
44
+ color: #5e35b1;
45
+ }
46
+
47
+ .connection-status {
48
+ display: flex;
49
+ align-items: center;
50
+ gap: 6px;
51
+ font-size: 12px;
52
+ font-weight: 500;
53
+ color: #444;
54
+ }
55
+
56
+ .divider {
57
+ width: 100%;
58
+ height: 2px;
59
+ background: #e0e0e0;
60
+ margin: 8px 0;
61
+ }
62
+
63
+ .status-indicator {
64
+ width: 8px;
65
+ height: 8px;
66
+ border-radius: 50%;
67
+ background: #f44336;
68
+ transition: background-color 0.2s;
69
+ }
70
+
71
+ .status-indicator.connected {
72
+ background: #4caf50;
73
+ }
74
+
75
+ .status-indicator.connecting {
76
+ background: #ff9800;
77
+ animation: pulse 2s infinite;
78
+ }
79
+
80
+ .status-indicator.warning {
81
+ background: #ff9800;
82
+ }
83
+
84
+ .status-indicator.disconnected {
85
+ background: #f44336;
86
+ }
87
+
88
+ @keyframes pulse {
89
+ 0%, 100% { opacity: 1; }
90
+ 50% { opacity: 0.5; }
91
+ }
92
+
93
+ .header-controls {
94
+ display: flex;
95
+ gap: 8px;
96
+ }
97
+
98
+ /* Buttons */
99
+ .btn {
100
+ border: 1px solid #ccc;
101
+ background: #fff;
102
+ color: #333;
103
+ padding: 4px 12px;
104
+ border-radius: 4px;
105
+ font-size: 12px;
106
+ cursor: pointer;
107
+ transition: all 0.2s;
108
+ }
109
+
110
+ .btn:hover {
111
+ background: #f0f0f0;
112
+ }
113
+
114
+ .btn.btn-primary {
115
+ background: #2196f3;
116
+ border-color: #2196f3;
117
+ color: white;
118
+ }
119
+
120
+ .btn.btn-primary:hover {
121
+ background: #1976d2;
122
+ }
123
+
124
+ .btn.btn-secondary {
125
+ background: #f5f5f5;
126
+ }
127
+
128
+ .btn:disabled {
129
+ opacity: 0.5;
130
+ cursor: not-allowed;
131
+ }
132
+
133
+ .btn.active {
134
+ background: #673ab7;
135
+ border-color: #673ab7;
136
+ color: white;
137
+ }
138
+
139
+ .btn.active:hover {
140
+ background: #5e35b1;
141
+ border-color: #5e35b1;
142
+ }
143
+
144
+ /* Settings Panel */
145
+ .settings-panel {
146
+ position: absolute;
147
+ top: 49px;
148
+ right: 12px;
149
+ left: auto;
150
+ width: 320px;
151
+ background: white;
152
+ border: 1px solid #d0d0d0;
153
+ border-radius: 8px;
154
+ box-shadow: 0 4px 16px rgba(0,0,0,0.15);
155
+ z-index: 1000;
156
+ max-height: 400px;
157
+ overflow-y: auto;
158
+ }
159
+
160
+ .settings-content {
161
+ padding: 16px;
162
+ }
163
+
164
+ .settings-content h3 {
165
+ margin-bottom: 16px;
166
+ font-size: 14px;
167
+ font-weight: 600;
168
+ }
169
+
170
+ .setting-group {
171
+ margin-bottom: 12px;
172
+ }
173
+
174
+ .setting-group label {
175
+ display: block;
176
+ margin-bottom: 4px;
177
+ font-weight: 500;
178
+ }
179
+
180
+ .setting-group input[type="checkbox"] {
181
+ margin-right: 8px;
182
+ }
183
+
184
+ .setting-group input[type="number"],
185
+ .setting-group textarea {
186
+ width: 100%;
187
+ padding: 6px 8px;
188
+ border: 1px solid #ccc;
189
+ border-radius: 4px;
190
+ font-size: 12px;
191
+ }
192
+
193
+ .setting-group textarea {
194
+ height: 60px;
195
+ resize: vertical;
196
+ font-family: monospace;
197
+ }
198
+
199
+ .settings-actions {
200
+ margin-top: 16px;
201
+ display: flex;
202
+ gap: 8px;
203
+ justify-content: flex-end;
204
+ }
205
+
206
+ /* Tabs */
207
+ .tabs {
208
+ background: #fff;
209
+ border-bottom: 1px solid #e0e0e0;
210
+ display: flex;
211
+ flex-shrink: 0;
212
+ padding: 0 8px;
213
+ }
214
+
215
+ .tab {
216
+ padding: 10px 20px;
217
+ border: 1px solid transparent;
218
+ border-bottom: none;
219
+ background: none;
220
+ cursor: pointer;
221
+ font-size: 13px;
222
+ font-weight: 500;
223
+ color: #555;
224
+ transition: all 0.2s;
225
+ margin-top: 4px;
226
+ border-radius: 6px 6px 0 0;
227
+ }
228
+
229
+ .tab:hover {
230
+ color: #333;
231
+ background: #f0f0f0;
232
+ }
233
+
234
+ .tab.active {
235
+ color: #673ab7;
236
+ background: #f5f0ff;
237
+ border-color: #d0c0e8;
238
+ border-bottom: 2px solid #fff;
239
+ margin-bottom: -1px;
240
+ font-weight: 600;
241
+ }
242
+
243
+ /* Main Content */
244
+ .main-content {
245
+ flex: 1;
246
+ overflow: hidden;
247
+ position: relative;
248
+ display: flex;
249
+ flex-direction: column;
250
+ }
251
+
252
+ .tab-content {
253
+ flex: 1;
254
+ overflow: hidden;
255
+ }
256
+
257
+ /* Empty State */
258
+ .empty-state {
259
+ display: flex;
260
+ align-items: center;
261
+ justify-content: center;
262
+ height: 100%;
263
+ text-align: center;
264
+ }
265
+
266
+ .empty-state-content h2 {
267
+ font-size: 18px;
268
+ margin-bottom: 8px;
269
+ color: #666;
270
+ }
271
+
272
+ .empty-state-content p {
273
+ color: #999;
274
+ margin-bottom: 16px;
275
+ }
276
+
277
+ /* Updates Container */
278
+ .updates-container {
279
+ height: 100%;
280
+ display: flex;
281
+ flex-direction: column;
282
+ }
283
+
284
+ .updates-header {
285
+ background: #fff;
286
+ border-bottom: 1px solid #e0e0e0;
287
+ padding: 8px 12px;
288
+ flex-shrink: 0;
289
+ }
290
+
291
+ .updates-stats {
292
+ display: flex;
293
+ gap: 16px;
294
+ font-size: 12px;
295
+ color: #666;
296
+ }
297
+
298
+ .updates-list {
299
+ flex: 1;
300
+ overflow-y: auto;
301
+ padding: 8px;
302
+ }
303
+
304
+ /* Update Items */
305
+ .update-item {
306
+ background: white;
307
+ border: 1px solid #e0e0e0;
308
+ border-radius: 4px;
309
+ margin-bottom: 8px;
310
+ padding: 8px;
311
+ font-size: 12px;
312
+ }
313
+
314
+ .update-item.effect {
315
+ border-left: 4px solid #ff9800;
316
+ }
317
+
318
+ .component-name-header {
319
+ margin-right: 8px;
320
+ }
321
+
322
+ .component-list {
323
+ list-style: none;
324
+ display: flex;
325
+ padding: 0;
326
+ margin: 0;
327
+ font-family: monospace;
328
+ background: #f8f9fa;
329
+ padding: 4px 6px;
330
+ border-radius: 3px;
331
+ }
332
+
333
+ .update-item.rerender {
334
+ border-left: 4px solid #9c27b0;
335
+ background-color: #fafafa;
336
+ }
337
+
338
+ .update-item.value {
339
+ border-left: 4px solid #2196f3;
340
+ }
341
+
342
+ .update-header {
343
+ display: flex;
344
+ justify-content: space-between;
345
+ align-items: center;
346
+ margin-bottom: 4px;
347
+ }
348
+
349
+ .update-count {
350
+ display: inline-block;
351
+ padding: 0 6px;
352
+ background: #e0e0e0;
353
+ border-radius: 12px;
354
+ margin: 0 2px;
355
+ }
356
+
357
+ .signal-name {
358
+ font-weight: 600;
359
+ color: #5e35b1;
360
+ }
361
+
362
+ .component-name {
363
+ font-weight: 500;
364
+ color: #1565c0;
365
+ font-style: italic;
366
+ }
367
+
368
+ .update-time {
369
+ color: #757575;
370
+ font-size: 11px;
371
+ }
372
+
373
+ .update-depth {
374
+ color: #555;
375
+ font-size: 11px;
376
+ }
377
+
378
+ .value-change {
379
+ margin: 4px 0;
380
+ font-family: monospace;
381
+ background: #f8f9fa;
382
+ padding: 4px 6px;
383
+ border-radius: 3px;
384
+ }
385
+
386
+ .value-prev,
387
+ .value-new {
388
+ display: inline-block;
389
+ max-width: 200px;
390
+ overflow: hidden;
391
+ text-overflow: ellipsis;
392
+ white-space: nowrap;
393
+ vertical-align: top;
394
+ }
395
+
396
+ .value-prev {
397
+ color: #d32f2f;
398
+ }
399
+
400
+ .value-new {
401
+ color: #388e3c;
402
+ }
403
+
404
+ .value-arrow {
405
+ margin: 0 8px;
406
+ color: #666;
407
+ }
408
+
409
+ /* Scrollbar styling */
410
+ .updates-list::-webkit-scrollbar {
411
+ width: 8px;
412
+ }
413
+
414
+ .updates-list::-webkit-scrollbar-track {
415
+ background: #f5f5f5;
416
+ }
417
+
418
+ .updates-list::-webkit-scrollbar-thumb {
419
+ background: #ccc;
420
+ border-radius: 4px;
421
+ }
422
+
423
+ .updates-list::-webkit-scrollbar-thumb:hover {
424
+ background: #999;
425
+ }
426
+
427
+ /* Graph Visualization */
428
+ .graph-container {
429
+ height: 100%;
430
+ display: flex;
431
+ flex-direction: column;
432
+ }
433
+
434
+ .graph-content {
435
+ flex: 1;
436
+ position: relative;
437
+ background:
438
+ linear-gradient(90deg, #e5e7eb 1px, transparent 1px),
439
+ linear-gradient(180deg, #e5e7eb 1px, transparent 1px),
440
+ #f8fafc;
441
+ background-size: 40px 40px;
442
+ overflow: hidden;
443
+ user-select: none;
444
+ }
445
+
446
+ .graph-svg {
447
+ width: 100%;
448
+ height: 100%;
449
+ min-height: 500px;
450
+ }
451
+
452
+ .graph-controls {
453
+ position: absolute;
454
+ top: 16px;
455
+ left: 16px;
456
+ display: flex;
457
+ gap: 8px;
458
+ z-index: 10;
459
+ }
460
+
461
+ .graph-reset-button,
462
+ .graph-export-button {
463
+ background: rgba(255, 255, 255, 0.95);
464
+ backdrop-filter: blur(4px);
465
+ border: 1px solid #e2e8f0;
466
+ border-radius: 6px;
467
+ color: #334155;
468
+ padding: 8px 14px;
469
+ font-size: 12px;
470
+ font-weight: 500;
471
+ cursor: pointer;
472
+ box-shadow: 0 2px 6px rgba(0,0,0,0.08);
473
+ transition: all 0.15s ease;
474
+ }
475
+
476
+ .graph-reset-button:hover,
477
+ .graph-export-button:hover {
478
+ background: #fff;
479
+ border-color: #cbd5e1;
480
+ box-shadow: 0 4px 8px rgba(0,0,0,0.12);
481
+ transform: translateY(-1px);
482
+ }
483
+
484
+ .graph-reset-button:active,
485
+ .graph-export-button:active {
486
+ background: #eeeeee;
487
+ transform: translateY(1px);
488
+ }
489
+
490
+ .graph-export-container {
491
+ position: relative;
492
+ }
493
+
494
+ .graph-export-menu {
495
+ position: absolute;
496
+ top: 100%;
497
+ left: 0;
498
+ margin-top: 4px;
499
+ background: white;
500
+ border: 1px solid #e0e0e0;
501
+ border-radius: 4px;
502
+ box-shadow: 0 4px 8px rgba(0,0,0,0.15);
503
+ overflow: hidden;
504
+ min-width: 180px;
505
+ }
506
+
507
+ .graph-export-menu-item {
508
+ display: block;
509
+ width: 100%;
510
+ background: white;
511
+ border: none;
512
+ padding: 10px 12px;
513
+ font-size: 12px;
514
+ text-align: left;
515
+ cursor: pointer;
516
+ transition: background 0.2s;
517
+ white-space: nowrap;
518
+ }
519
+
520
+ .graph-export-menu-item:hover {
521
+ background: #f5f5f5;
522
+ }
523
+
524
+ .graph-export-menu-item:active {
525
+ background: #eeeeee;
526
+ }
527
+
528
+ .graph-export-menu-item:not(:last-child) {
529
+ border-bottom: 1px solid #e0e0e0;
530
+ }
531
+
532
+ .graph-zoom-indicator {
533
+ background: rgba(255, 255, 255, 0.9);
534
+ backdrop-filter: blur(4px);
535
+ border: 1px solid #e0e0e0;
536
+ border-radius: 4px;
537
+ color: #64748b;
538
+ padding: 6px 10px;
539
+ font-size: 11px;
540
+ font-weight: 600;
541
+ font-family: monospace;
542
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
543
+ min-width: 48px;
544
+ text-align: center;
545
+ }
546
+
547
+ .graph-node {
548
+ cursor: pointer;
549
+ transition: transform 0.15s ease, filter 0.15s ease;
550
+ stroke: #fff;
551
+ stroke-width: 2.5;
552
+ filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15));
553
+ }
554
+
555
+ .graph-node-group.hovered .graph-node {
556
+ filter: brightness(1.15) drop-shadow(0 4px 12px rgba(0,0,0,0.25));
557
+ stroke-width: 3;
558
+ }
559
+
560
+ .graph-node.signal {
561
+ fill: #2196f3;
562
+ }
563
+
564
+ .graph-node.computed {
565
+ fill: #ff9800;
566
+ }
567
+
568
+ .graph-node.effect {
569
+ fill: #4caf50;
570
+ }
571
+
572
+ .graph-node.component {
573
+ fill: #9c27b0;
574
+ }
575
+
576
+ .graph-link {
577
+ stroke: #94a3b8;
578
+ stroke-width: 2;
579
+ fill: none;
580
+ transition: stroke 0.2s, stroke-width 0.2s;
581
+ }
582
+
583
+ .graph-link.highlighted {
584
+ stroke: #673ab7;
585
+ stroke-width: 3;
586
+ }
587
+
588
+ .graph-text {
589
+ fill: white;
590
+ text-anchor: middle;
591
+ dominant-baseline: central;
592
+ font-size: 12px;
593
+ font-weight: 600;
594
+ pointer-events: none;
595
+ text-shadow: 0 1px 3px rgba(0,0,0,0.4);
596
+ letter-spacing: 0.2px;
597
+ }
598
+
599
+ /* Tooltip */
600
+ .graph-tooltip {
601
+ position: absolute;
602
+ background: #1e293b;
603
+ color: white;
604
+ padding: 10px 14px;
605
+ border-radius: 8px;
606
+ font-size: 12px;
607
+ box-shadow: 0 8px 24px rgba(0,0,0,0.25);
608
+ z-index: 1000;
609
+ pointer-events: none;
610
+ transform: translateY(-50%);
611
+ max-width: 280px;
612
+ animation: tooltipFadeIn 0.15s ease-out;
613
+ }
614
+
615
+ @keyframes tooltipFadeIn {
616
+ from {
617
+ opacity: 0;
618
+ transform: translateY(-50%) translateX(-4px);
619
+ }
620
+ to {
621
+ opacity: 1;
622
+ transform: translateY(-50%) translateX(0);
623
+ }
624
+ }
625
+
626
+ .tooltip-header {
627
+ margin-bottom: 6px;
628
+ }
629
+
630
+ .tooltip-type {
631
+ display: inline-block;
632
+ padding: 2px 8px;
633
+ border-radius: 4px;
634
+ font-size: 10px;
635
+ font-weight: 600;
636
+ text-transform: uppercase;
637
+ letter-spacing: 0.5px;
638
+ }
639
+
640
+ .tooltip-type.signal {
641
+ background: #2196f3;
642
+ }
643
+
644
+ .tooltip-type.computed {
645
+ background: #ff9800;
646
+ }
647
+
648
+ .tooltip-type.effect {
649
+ background: #4caf50;
650
+ }
651
+
652
+ .tooltip-type.component {
653
+ background: #9c27b0;
654
+ }
655
+
656
+ .tooltip-name {
657
+ font-size: 14px;
658
+ font-weight: 600;
659
+ margin-bottom: 4px;
660
+ word-break: break-word;
661
+ }
662
+
663
+ .tooltip-id {
664
+ color: #94a3b8;
665
+ font-size: 11px;
666
+ font-family: monospace;
667
+ }
668
+
669
+ .graph-legend {
670
+ position: absolute;
671
+ top: 16px;
672
+ right: 16px;
673
+ background: rgba(255, 255, 255, 0.95);
674
+ backdrop-filter: blur(8px);
675
+ border: 1px solid #e2e8f0;
676
+ border-radius: 8px;
677
+ padding: 14px 16px;
678
+ font-size: 12px;
679
+ box-shadow: 0 4px 12px rgba(0,0,0,0.08);
680
+ }
681
+
682
+ .legend-item {
683
+ display: flex;
684
+ align-items: center;
685
+ gap: 10px;
686
+ margin-bottom: 8px;
687
+ }
688
+
689
+ .legend-item:last-child {
690
+ margin-bottom: 0;
691
+ }
692
+
693
+ .legend-color {
694
+ width: 14px;
695
+ height: 14px;
696
+ border-radius: 50%;
697
+ box-shadow: 0 2px 4px rgba(0,0,0,0.15);
698
+ }
699
+
700
+ .component-boundary {
701
+ transition: all 0.2s ease;
702
+ }
703
+
704
+ .component-boundary:hover {
705
+ fill: rgba(100, 149, 237, 0.15);
706
+ stroke: rgba(100, 149, 237, 0.5);
707
+ }
708
+
709
+ .component-label {
710
+ user-select: none;
711
+ pointer-events: none;
712
+ }
713
+
714
+ .graph-empty {
715
+ display: flex;
716
+ align-items: center;
717
+ justify-content: center;
718
+ height: 100%;
719
+ text-align: center;
720
+ color: #666;
721
+ }
722
+
723
+ .graph-toast {
724
+ position: absolute;
725
+ top: 16px;
726
+ right: 16px;
727
+ background: #323232;
728
+ color: white;
729
+ padding: 12px 16px;
730
+ border-radius: 4px;
731
+ font-size: 13px;
732
+ font-weight: 500;
733
+ box-shadow: 0 4px 12px rgba(0,0,0,0.3);
734
+ z-index: 1000;
735
+ animation: slideInFade 0.3s ease-out;
736
+ }
737
+
738
+ @keyframes slideInFade {
739
+ from {
740
+ opacity: 0;
741
+ transform: translateY(-8px);
742
+ }
743
+ to {
744
+ opacity: 1;
745
+ transform: translateY(0);
746
+ }
747
+ }
748
+
749
+ /* Tree Node Styles */
750
+ .tree-node {
751
+ margin-bottom: 4px;
752
+ }
753
+
754
+ .tree-node-content {
755
+ display: flex;
756
+ align-items: flex-start;
757
+ gap: 4px;
758
+ }
759
+
760
+ .collapse-button {
761
+ background: none;
762
+ border: none;
763
+ color: #666;
764
+ cursor: pointer;
765
+ font-size: 12px;
766
+ width: 16px;
767
+ height: 16px;
768
+ display: flex;
769
+ align-items: center;
770
+ justify-content: center;
771
+ padding: 0;
772
+ margin-top: 8px;
773
+ flex-shrink: 0;
774
+ transition: color 0.2s;
775
+ }
776
+
777
+ .collapse-button:hover {
778
+ color: #333;
779
+ background: #f0f0f0;
780
+ border-radius: 2px;
781
+ }
782
+
783
+ .collapse-spacer {
784
+ width: 16px;
785
+ height: 16px;
786
+ flex-shrink: 0;
787
+ margin-top: 8px;
788
+ }
789
+
790
+ .update-content {
791
+ flex: 1;
792
+ min-width: 0;
793
+ }
794
+
795
+ .tree-children {
796
+ margin-left: 20px;
797
+ border-left: 1px solid #e0e0e0;
798
+ padding-left: 4px;
799
+ margin-top: 4px;
800
+ }
801
+
802
+ .tree-children .tree-node:last-child {
803
+ margin-bottom: 0;
804
+ }
805
+
806
+ /* Update existing update-item styles to work better with tree */
807
+ .tree-node .update-item {
808
+ margin-bottom: 0;
809
+ }
810
+
811
+ /* Responsive adjustments */
812
+ @media (max-width: 600px) {
813
+ .header {
814
+ flex-direction: column;
815
+ gap: 8px;
816
+ align-items: stretch;
817
+ }
818
+
819
+ .header-title {
820
+ justify-content: center;
821
+ }
822
+
823
+ .header-controls {
824
+ justify-content: center;
825
+ }
826
+
827
+ .graph-legend {
828
+ position: static;
829
+ margin: 16px;
830
+ }
831
+
832
+ .tree-children {
833
+ margin-left: 12px;
834
+ }
835
+ }