@dfosco/storyboard-react 4.2.0-beta.0 → 4.2.0-beta.17

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.
Files changed (48) hide show
  1. package/package.json +5 -4
  2. package/src/AuthModal/AuthModal.jsx +6 -2
  3. package/src/BranchBar/BranchBar.jsx +17 -5
  4. package/src/BranchBar/BranchBar.module.css +11 -2
  5. package/src/CommandPalette/CommandPalette.jsx +267 -164
  6. package/src/CommandPalette/command-palette.css +130 -78
  7. package/src/Icon.jsx +112 -48
  8. package/src/Viewfinder.jsx +511 -61
  9. package/src/Viewfinder.module.css +414 -2
  10. package/src/canvas/CanvasPage.bridge.test.jsx +14 -6
  11. package/src/canvas/CanvasPage.dragdrop.test.jsx +10 -6
  12. package/src/canvas/CanvasPage.jsx +157 -174
  13. package/src/canvas/CanvasPage.module.css +0 -15
  14. package/src/canvas/CanvasPage.multiselect.test.jsx +10 -6
  15. package/src/canvas/ConnectorLayer.jsx +5 -5
  16. package/src/canvas/PageSelector.test.jsx +15 -6
  17. package/src/canvas/useCanvas.js +1 -1
  18. package/src/canvas/widgets/ActionWidget.jsx +200 -0
  19. package/src/canvas/widgets/ActionWidget.module.css +122 -0
  20. package/src/canvas/widgets/FigmaEmbed.jsx +97 -29
  21. package/src/canvas/widgets/FigmaEmbed.module.css +61 -0
  22. package/src/canvas/widgets/ImageWidget.jsx +1 -1
  23. package/src/canvas/widgets/LinkPreview.jsx +64 -5
  24. package/src/canvas/widgets/LinkPreview.module.css +127 -0
  25. package/src/canvas/widgets/MarkdownBlock.jsx +39 -17
  26. package/src/canvas/widgets/MarkdownBlock.module.css +123 -0
  27. package/src/canvas/widgets/PrototypeEmbed.jsx +183 -20
  28. package/src/canvas/widgets/PrototypeEmbed.module.css +117 -0
  29. package/src/canvas/widgets/PrototypeEmbed.test.jsx +2 -2
  30. package/src/canvas/widgets/SplitExpandModal.jsx +234 -0
  31. package/src/canvas/widgets/SplitExpandModal.module.css +335 -0
  32. package/src/canvas/widgets/SplitScreenTopBar.jsx +30 -0
  33. package/src/canvas/widgets/SplitScreenTopBar.module.css +58 -0
  34. package/src/canvas/widgets/StoryWidget.jsx +7 -4
  35. package/src/canvas/widgets/TerminalReadWidget.jsx +140 -0
  36. package/src/canvas/widgets/TerminalReadWidget.module.css +92 -0
  37. package/src/canvas/widgets/TerminalWidget.jsx +299 -49
  38. package/src/canvas/widgets/TerminalWidget.module.css +155 -1
  39. package/src/canvas/widgets/WidgetChrome.jsx +19 -14
  40. package/src/canvas/widgets/WidgetChrome.module.css +10 -0
  41. package/src/canvas/widgets/embedInteraction.test.jsx +24 -26
  42. package/src/canvas/widgets/expandUtils.js +188 -0
  43. package/src/canvas/widgets/index.js +5 -0
  44. package/src/canvas/widgets/snapshotDisplay.test.jsx +23 -71
  45. package/src/canvas/widgets/widgetConfig.js +19 -1
  46. package/src/hooks/useConfig.js +14 -0
  47. package/src/index.js +4 -0
  48. package/src/vite/data-plugin.js +264 -14
@@ -42,8 +42,7 @@
42
42
 
43
43
  .appName {
44
44
  font-size: 24px;
45
- /* font-style: italic; */
46
- font-weight: 900;
45
+ font-weight: 800;
47
46
  color: var(--fgColor-default, #1a1a1a);
48
47
  line-height: 1.1;
49
48
  }
@@ -249,6 +248,7 @@
249
248
  }
250
249
 
251
250
  .navIcon {
251
+ color: var(--fgColor-default, #1a1a1a);
252
252
  width: 18px;
253
253
  height: 18px;
254
254
  display: flex;
@@ -380,6 +380,247 @@
380
380
  border-color: var(--borderColor-muted);
381
381
  }
382
382
 
383
+ .userAvatar {
384
+ width: 32px;
385
+ height: 32px;
386
+ border-radius: 50%;
387
+ object-fit: cover;
388
+ flex-shrink: 0;
389
+ }
390
+
391
+ .footerRow {
392
+ display: flex;
393
+ align-items: center;
394
+ gap: 6px;
395
+ }
396
+
397
+ .userBtn {
398
+ display: flex;
399
+ align-items: center;
400
+ gap: 10px;
401
+ flex: 1;
402
+ min-width: 0;
403
+ padding: 8px 10px;
404
+ background: none;
405
+ border: 1px solid var(--borderColor-default, #e5e5e5);
406
+ border-radius: 8px;
407
+ font-size: 16px;
408
+ color: var(--fgColor-muted, #555);
409
+ cursor: pointer;
410
+ transition: all 0.15s;
411
+ text-align: left;
412
+ }
413
+
414
+ .userBtn:hover {
415
+ background: var(--bgColor-muted, #f5f5f5);
416
+ border-color: var(--borderColor-muted);
417
+ }
418
+
419
+ .userInfo {
420
+ flex: 1;
421
+ min-width: 0;
422
+ overflow: hidden;
423
+ text-overflow: ellipsis;
424
+ white-space: nowrap;
425
+ }
426
+
427
+ .gearBtn {
428
+ display: flex;
429
+ align-items: center;
430
+ justify-content: center;
431
+ width: 36px;
432
+ height: 36px;
433
+ flex-shrink: 0;
434
+ background: none;
435
+ border: 1px solid var(--borderColor-default, #e5e5e5);
436
+ border-radius: 8px;
437
+ color: var(--fgColor-muted, #888);
438
+ cursor: pointer;
439
+ transition: all 0.15s;
440
+ }
441
+
442
+ .gearBtn:hover {
443
+ background: var(--bgColor-muted, #f5f5f5);
444
+ border-color: var(--borderColor-muted);
445
+ color: var(--fgColor-default, #333);
446
+ }
447
+
448
+ /* ─── Settings Dialog ─── */
449
+
450
+ .settingsBackdrop {
451
+ position: fixed;
452
+ inset: 0;
453
+ background: var(--overlay-backdrop-bgColor, rgba(0, 0, 0, 0.4));
454
+ z-index: 10000;
455
+ }
456
+
457
+ .settingsPopupWrap {
458
+ position: fixed;
459
+ inset: 0;
460
+ z-index: 10001;
461
+ display: flex;
462
+ align-items: center;
463
+ justify-content: center;
464
+ pointer-events: none;
465
+ }
466
+
467
+ .settingsPopupWrap > * {
468
+ pointer-events: auto;
469
+ }
470
+
471
+ .settingsPopup {
472
+ background: var(--bgColor-default);
473
+ border-radius: 12px;
474
+ box-shadow: var(--shadow-overlay, 0 16px 48px rgba(0, 0, 0, 0.12));
475
+ padding: 28px;
476
+ max-width: 480px;
477
+ width: 90vw;
478
+ max-height: 90vh;
479
+ overflow-y: auto;
480
+ color: var(--fgColor-default);
481
+ position: relative;
482
+ }
483
+
484
+ .settingsTitle {
485
+ font-size: 18px;
486
+ font-weight: 600;
487
+ margin-bottom: 20px;
488
+ color: var(--fgColor-default);
489
+ padding-right: 32px;
490
+ }
491
+
492
+ .settingsCloseBtn {
493
+ position: absolute;
494
+ top: 16px;
495
+ right: 16px;
496
+ background: none;
497
+ border: none;
498
+ font-size: 24px;
499
+ line-height: 1;
500
+ color: var(--fgColor-muted);
501
+ cursor: pointer;
502
+ padding: 4px 8px;
503
+ border-radius: 4px;
504
+ }
505
+
506
+ .settingsCloseBtn:hover {
507
+ background: var(--bgColor-neutral-muted);
508
+ color: var(--fgColor-default);
509
+ }
510
+
511
+ .settingsSection {
512
+ margin-bottom: 20px;
513
+ }
514
+
515
+ .settingsSectionHeader {
516
+ display: flex;
517
+ align-items: center;
518
+ gap: 8px;
519
+ font-size: 14px;
520
+ font-weight: 600;
521
+ color: var(--fgColor-muted);
522
+ text-transform: uppercase;
523
+ letter-spacing: 0.03em;
524
+ margin-bottom: 12px;
525
+ }
526
+
527
+ .settingsTokenCard {
528
+ background: var(--bgColor-muted);
529
+ border: 1px solid var(--borderColor-default);
530
+ border-radius: 8px;
531
+ padding: 14px 16px;
532
+ }
533
+
534
+ .settingsTokenRow {
535
+ display: flex;
536
+ align-items: baseline;
537
+ gap: 10px;
538
+ font-size: 14px;
539
+ line-height: 2;
540
+ color: var(--fgColor-muted);
541
+ }
542
+
543
+ .settingsTokenLabel {
544
+ flex-shrink: 0;
545
+ min-width: 90px;
546
+ font-weight: 500;
547
+ color: var(--fgColor-default);
548
+ }
549
+
550
+ .settingsTokenValue {
551
+ font-family: 'SF Mono', SFMono-Regular, Consolas, 'Liberation Mono', Menlo, monospace;
552
+ font-size: 13px;
553
+ color: var(--fgColor-muted);
554
+ display: flex;
555
+ flex-wrap: wrap;
556
+ gap: 4px;
557
+ align-items: center;
558
+ }
559
+
560
+ .settingsScope {
561
+ font-family: 'SF Mono', SFMono-Regular, Consolas, 'Liberation Mono', Menlo, monospace;
562
+ font-size: 12px;
563
+ color: var(--fgColor-default);
564
+ background: var(--bgColor-default);
565
+ padding: 1px 6px;
566
+ border-radius: 4px;
567
+ border: 1px solid var(--borderColor-default);
568
+ }
569
+
570
+ .settingsRemoveBtn {
571
+ display: flex;
572
+ align-items: center;
573
+ gap: 6px;
574
+ margin-top: 12px;
575
+ padding: 6px 12px;
576
+ background: none;
577
+ border: 1px solid var(--borderColor-danger-muted, #ff818266);
578
+ border-radius: 6px;
579
+ font-size: 13px;
580
+ color: var(--fgColor-danger, #d1242f);
581
+ cursor: pointer;
582
+ transition: all 0.15s;
583
+ }
584
+
585
+ .settingsRemoveBtn:hover {
586
+ background: var(--bgColor-danger-muted, #ffebe966);
587
+ border-color: var(--borderColor-danger-emphasis, #cf222e);
588
+ }
589
+
590
+ .settingsNoToken {
591
+ background: var(--bgColor-muted);
592
+ border: 1px solid var(--borderColor-default);
593
+ border-radius: 8px;
594
+ padding: 16px;
595
+ text-align: center;
596
+ color: var(--fgColor-muted);
597
+ font-size: 14px;
598
+ }
599
+
600
+ .settingsNoToken p {
601
+ margin-bottom: 12px;
602
+ }
603
+
604
+ .settingsSignInBtn {
605
+ display: inline-flex;
606
+ align-items: center;
607
+ gap: 8px;
608
+ padding: 8px 16px;
609
+ background: var(--bgColor-default);
610
+ border: 1px solid var(--borderColor-default);
611
+ border-radius: 6px;
612
+ font-size: 14px;
613
+ font-weight: 500;
614
+ color: var(--fgColor-default);
615
+ cursor: pointer;
616
+ transition: all 0.15s;
617
+ }
618
+
619
+ .settingsSignInBtn:hover {
620
+ background: var(--bgColor-muted);
621
+ border-color: var(--borderColor-muted);
622
+ }
623
+
383
624
  /* ─── Main Content ─── */
384
625
 
385
626
  .main {
@@ -1190,4 +1431,175 @@
1190
1431
  .groupByFolders {
1191
1432
  display: none;
1192
1433
  }
1434
+
1435
+ .logo {
1436
+ display: none;
1437
+ }
1438
+
1439
+ .appSubtitle {
1440
+ display: none;
1441
+ }
1442
+ }
1443
+
1444
+ /* Title row: flex container for title + inline star */
1445
+ .cardTitleRow {
1446
+ display: flex;
1447
+ align-items: center;
1448
+ gap: 4px;
1449
+ }
1450
+
1451
+ /* Inline star button variants */
1452
+ .iconBtnInline {
1453
+ composes: iconBtn;
1454
+ width: 28px;
1455
+ height: 28px;
1456
+ flex-shrink: 0;
1457
+ margin: -2px -4px -2px 0;
1458
+ }
1459
+
1460
+ .iconBtnInlineActive {
1461
+ composes: iconBtnInline;
1462
+ color: var(--fgColor-attention, #f59e0b);
1463
+ }
1464
+
1465
+ .iconBtnInlineActive:hover {
1466
+ background: rgba(0, 0, 0, 0.06);
1467
+ color: var(--fgColor-attention, #d97706);
1468
+ }
1469
+
1470
+ /* Card actions dropdown menu */
1471
+ .actionsMenuPositioner {
1472
+ z-index: 200;
1473
+ }
1474
+
1475
+ .actionsMenu {
1476
+ background: var(--bgColor-default, #fff);
1477
+ border: 1px solid var(--borderColor-default, #e5e5e5);
1478
+ border-radius: 8px;
1479
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
1480
+ padding: 4px;
1481
+ min-width: 160px;
1482
+ font-family: 'Mona Sans', -apple-system, BlinkMacSystemFont, sans-serif;
1483
+ }
1484
+
1485
+ .actionsMenuItem {
1486
+ display: flex;
1487
+ align-items: center;
1488
+ gap: 8px;
1489
+ width: 100%;
1490
+ padding: 8px 12px;
1491
+ border: none;
1492
+ background: none;
1493
+ border-radius: 6px;
1494
+ cursor: pointer;
1495
+ font-size: 14px;
1496
+ color: var(--fgColor-default, #1a1a1a);
1497
+ text-align: left;
1498
+ }
1499
+
1500
+ .actionsMenuItem:hover {
1501
+ background: var(--bgColor-neutral-muted, #f0f0f0);
1502
+ }
1503
+
1504
+ .actionsMenuItemDanger {
1505
+ composes: actionsMenuItem;
1506
+ color: var(--fgColor-danger, #cf222e);
1507
+ }
1508
+
1509
+ .actionsMenuItemDanger:hover {
1510
+ background: var(--bgColor-danger-muted, #fff0f0);
1511
+ color: var(--fgColor-danger, #cf222e);
1512
+ }
1513
+
1514
+ /* Modal overlay and content */
1515
+ .modalOverlay {
1516
+ position: fixed;
1517
+ inset: 0;
1518
+ background: rgba(0, 0, 0, 0.4);
1519
+ display: flex;
1520
+ align-items: center;
1521
+ justify-content: center;
1522
+ z-index: 300;
1523
+ }
1524
+
1525
+ .modalContent {
1526
+ background: var(--bgColor-default, #fff);
1527
+ border: 1px solid var(--borderColor-default, #e5e5e5);
1528
+ border-radius: 12px;
1529
+ box-shadow: 0 12px 40px rgba(0, 0, 0, 0.12);
1530
+ padding: 16px;
1531
+ width: 380px;
1532
+ max-width: 90vw;
1533
+ font-family: 'Mona Sans', -apple-system, BlinkMacSystemFont, sans-serif;
1534
+ }
1535
+
1536
+ .modalActions {
1537
+ display: flex;
1538
+ align-items: center;
1539
+ gap: 8px;
1540
+ margin-top: 20px;
1541
+ justify-content: flex-end;
1542
+ }
1543
+
1544
+ .modalSubmitBtn {
1545
+ padding: 8px 16px;
1546
+ background: var(--fgColor-default, #1a1a1a);
1547
+ color: var(--bgColor-default, #fff);
1548
+ border: none;
1549
+ border-radius: 6px;
1550
+ font-size: 14px;
1551
+ font-weight: 600;
1552
+ cursor: pointer;
1553
+ transition: opacity 0.15s;
1554
+ }
1555
+
1556
+ .modalSubmitBtn:hover {
1557
+ opacity: 0.85;
1558
+ }
1559
+
1560
+ .modalSubmitBtn:disabled {
1561
+ opacity: 0.4;
1562
+ cursor: not-allowed;
1563
+ }
1564
+
1565
+ .modalCancelBtn {
1566
+ padding: 8px 16px;
1567
+ border: 1px solid var(--borderColor-default, #e5e5e5);
1568
+ border-radius: 6px;
1569
+ background: var(--bgColor-default, #fff);
1570
+ color: var(--fgColor-default, #1a1a1a);
1571
+ cursor: pointer;
1572
+ font-size: 14px;
1573
+ font-weight: 500;
1574
+ }
1575
+
1576
+ .modalCancelBtn:hover {
1577
+ background: var(--bgColor-neutral-muted, #f0f0f0);
1578
+ }
1579
+
1580
+ .deleteMessage {
1581
+ font-size: 14px;
1582
+ color: var(--fgColor-muted, #555);
1583
+ line-height: 1.5;
1584
+ margin: 12px 0;
1585
+ }
1586
+
1587
+ .deleteConfirmBtn {
1588
+ padding: 8px 16px;
1589
+ border: none;
1590
+ border-radius: 6px;
1591
+ background: var(--bgColor-danger-emphasis, #cf222e);
1592
+ color: #fff;
1593
+ cursor: pointer;
1594
+ font-size: 14px;
1595
+ font-weight: 600;
1596
+ }
1597
+
1598
+ .deleteConfirmBtn:hover {
1599
+ background: var(--bgColor-danger-emphasis, #a40e26);
1600
+ }
1601
+
1602
+ .deleteConfirmBtn:disabled {
1603
+ opacity: 0.6;
1604
+ cursor: not-allowed;
1193
1605
  }
@@ -63,12 +63,16 @@ vi.mock('./widgets/widgetProps.js', () => ({
63
63
  getDefaults: () => ({}),
64
64
  }))
65
65
 
66
- vi.mock('./widgets/widgetConfig.js', () => ({
67
- getFeatures: () => [],
68
- isResizable: () => false,
69
- schemas: {},
70
- getMenuWidgetTypes: () => [],
71
- }))
66
+ vi.mock('./widgets/widgetConfig.js', async () => {
67
+ const actual = await vi.importActual('./widgets/widgetConfig.js')
68
+ return {
69
+ getFeatures: () => [],
70
+ isResizable: () => false,
71
+ schemas: {},
72
+ getMenuWidgetTypes: () => [],
73
+ getConnectorDefaults: actual.getConnectorDefaults,
74
+ }
75
+ })
72
76
 
73
77
  vi.mock('./widgets/figmaUrl.js', () => ({
74
78
  isFigmaUrl: () => false,
@@ -129,6 +133,8 @@ describe('CanvasPage canvas bridge', () => {
129
133
  expect(window.__storyboardCanvasBridgeState).toEqual({
130
134
  active: true,
131
135
  canvasId: 'design-overview',
136
+ connectors: [],
137
+ widgets: [{ id: 'widget-1', type: 'mock-widget', position: { x: 10, y: 20 }, props: {} }],
132
138
  zoom: 100,
133
139
  })
134
140
  expect(mountedHandler).toHaveBeenCalled()
@@ -138,6 +144,8 @@ describe('CanvasPage canvas bridge', () => {
138
144
  expect(statusHandler.mock.calls.at(-1)?.[0]?.detail).toEqual({
139
145
  active: true,
140
146
  canvasId: 'design-overview',
147
+ connectors: [],
148
+ widgets: [{ id: 'widget-1', type: 'mock-widget', position: { x: 10, y: 20 }, props: {} }],
141
149
  zoom: 100,
142
150
  })
143
151
 
@@ -48,12 +48,16 @@ vi.mock('./widgets/widgetProps.js', () => ({
48
48
  getDefaults: () => ({}),
49
49
  }))
50
50
 
51
- vi.mock('./widgets/widgetConfig.js', () => ({
52
- getFeatures: () => [],
53
- isResizable: () => false,
54
- schemas: {},
55
- getMenuWidgetTypes: () => [],
56
- }))
51
+ vi.mock('./widgets/widgetConfig.js', async () => {
52
+ const actual = await vi.importActual('./widgets/widgetConfig.js')
53
+ return {
54
+ getFeatures: () => [],
55
+ isResizable: () => false,
56
+ schemas: {},
57
+ getMenuWidgetTypes: () => [],
58
+ getConnectorDefaults: actual.getConnectorDefaults,
59
+ }
60
+ })
57
61
 
58
62
  vi.mock('./widgets/figmaUrl.js', () => ({
59
63
  isFigmaUrl: () => false,