@dfosco/storyboard-react 4.0.0-beta.9 → 4.1.0-beta.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.
Files changed (75) hide show
  1. package/package.json +6 -3
  2. package/src/AuthModal/AuthModal.jsx +134 -0
  3. package/src/AuthModal/AuthModal.module.css +221 -0
  4. package/src/BranchBar/BranchBar.jsx +56 -0
  5. package/src/BranchBar/BranchBar.module.css +230 -0
  6. package/src/BranchBar/useBranches.js +79 -0
  7. package/src/CommandPalette/CommandPalette.jsx +936 -0
  8. package/src/CommandPalette/CreateDialog.jsx +219 -0
  9. package/src/CommandPalette/command-palette.css +111 -0
  10. package/src/Icon.jsx +180 -0
  11. package/src/Viewfinder.jsx +1104 -57
  12. package/src/Viewfinder.module.css +1107 -149
  13. package/src/canvas/CanvasControls.jsx +51 -2
  14. package/src/canvas/CanvasControls.module.css +31 -0
  15. package/src/canvas/CanvasPage.bridge.test.jsx +142 -19
  16. package/src/canvas/CanvasPage.dragdrop.test.jsx +346 -0
  17. package/src/canvas/CanvasPage.jsx +805 -251
  18. package/src/canvas/CanvasPage.module.css +98 -50
  19. package/src/canvas/CanvasPage.multiselect.test.jsx +13 -11
  20. package/src/canvas/CanvasToolbar.jsx +2 -2
  21. package/src/canvas/MarqueeOverlay.jsx +20 -0
  22. package/src/canvas/PageSelector.jsx +239 -0
  23. package/src/canvas/PageSelector.module.css +165 -0
  24. package/src/canvas/PageSelector.test.jsx +104 -0
  25. package/src/canvas/canvasApi.js +22 -8
  26. package/src/canvas/canvasTheme.js +96 -52
  27. package/src/canvas/componentIsolate.jsx +33 -7
  28. package/src/canvas/useCanvas.js +9 -8
  29. package/src/canvas/useCanvas.test.js +4 -4
  30. package/src/canvas/useMarqueeSelect.js +187 -0
  31. package/src/canvas/useMarqueeSelect.test.js +78 -0
  32. package/src/canvas/widgets/CodePenEmbed.jsx +292 -0
  33. package/src/canvas/widgets/CodePenEmbed.module.css +161 -0
  34. package/src/canvas/widgets/ComponentWidget.jsx +42 -10
  35. package/src/canvas/widgets/ComponentWidget.module.css +6 -5
  36. package/src/canvas/widgets/FigmaEmbed.jsx +110 -24
  37. package/src/canvas/widgets/FigmaEmbed.module.css +21 -7
  38. package/src/canvas/widgets/LinkPreview.jsx +297 -11
  39. package/src/canvas/widgets/LinkPreview.module.css +386 -18
  40. package/src/canvas/widgets/LinkPreview.test.jsx +193 -0
  41. package/src/canvas/widgets/MarkdownBlock.jsx +86 -5
  42. package/src/canvas/widgets/MarkdownBlock.module.css +64 -15
  43. package/src/canvas/widgets/PrototypeEmbed.jsx +96 -145
  44. package/src/canvas/widgets/PrototypeEmbed.module.css +74 -4
  45. package/src/canvas/widgets/StickyNote.module.css +5 -0
  46. package/src/canvas/widgets/StickyNote.test.jsx +9 -9
  47. package/src/canvas/widgets/StoryWidget.jsx +277 -0
  48. package/src/canvas/widgets/StoryWidget.module.css +211 -0
  49. package/src/canvas/widgets/WidgetChrome.jsx +76 -20
  50. package/src/canvas/widgets/WidgetChrome.module.css +2 -6
  51. package/src/canvas/widgets/WidgetWrapper.module.css +2 -0
  52. package/src/canvas/widgets/codepenUrl.js +75 -0
  53. package/src/canvas/widgets/codepenUrl.test.js +76 -0
  54. package/src/canvas/widgets/embedInteraction.test.jsx +235 -0
  55. package/src/canvas/widgets/embedOverlay.module.css +35 -0
  56. package/src/canvas/widgets/embedTheme.js +138 -39
  57. package/src/canvas/widgets/githubUrl.js +82 -0
  58. package/src/canvas/widgets/githubUrl.test.js +74 -0
  59. package/src/canvas/widgets/iframeDevLogs.js +49 -0
  60. package/src/canvas/widgets/iframeDevLogs.test.jsx +81 -0
  61. package/src/canvas/widgets/index.js +4 -0
  62. package/src/canvas/widgets/pasteRules.js +295 -0
  63. package/src/canvas/widgets/pasteRules.test.js +474 -0
  64. package/src/canvas/widgets/snapshotDisplay.test.jsx +259 -0
  65. package/src/canvas/widgets/widgetConfig.js +16 -5
  66. package/src/canvas/widgets/widgetConfig.test.js +34 -12
  67. package/src/context.jsx +145 -16
  68. package/src/hooks/useSceneData.js +4 -2
  69. package/src/hooks/useThemeState.js +61 -0
  70. package/src/hooks/useThemeState.test.js +66 -0
  71. package/src/index.js +10 -0
  72. package/src/story/StoryPage.jsx +117 -0
  73. package/src/story/StoryPage.module.css +18 -0
  74. package/src/vite/data-plugin.js +348 -66
  75. package/src/vite/data-plugin.test.js +405 -5
@@ -0,0 +1,79 @@
1
+ /**
2
+ * useBranches — shared hook for branch data across BranchBar and BranchDropdown.
3
+ * Fetches live branch list from /_storyboard/worktrees API on mount.
4
+ */
5
+ import { useState, useEffect, useMemo, useCallback } from 'react'
6
+
7
+ const isLocalDev = typeof window !== 'undefined' && window.__SB_LOCAL_DEV__ === true
8
+
9
+ export function useBranches(basePath) {
10
+ const [branches, setBranches] = useState(() => {
11
+ if (typeof window !== 'undefined' && Array.isArray(window.__SB_BRANCHES__)) {
12
+ return window.__SB_BRANCHES__
13
+ }
14
+ return null
15
+ })
16
+
17
+ const [gitUser, setGitUser] = useState(null)
18
+
19
+ useEffect(() => {
20
+ const apiBase = (basePath || '/').replace(/\/$/, '')
21
+
22
+ fetch(`${apiBase}/_storyboard/git-user`).then(r => r.ok ? r.json() : null)
23
+ .then(data => { if (data?.name) setGitUser(data.name) })
24
+ .catch(() => {})
25
+
26
+ // Always fetch live branch list
27
+ fetch(`${apiBase}/_storyboard/worktrees`).then(r => r.ok ? r.json() : null)
28
+ .then(data => { if (Array.isArray(data) && data.length > 0) setBranches(data) })
29
+ .catch(() => {})
30
+ }, [basePath])
31
+
32
+ const currentBranch = useMemo(() => {
33
+ const m = (basePath || '').match(/\/branch--([^/]+)\/?$/)
34
+ return m ? m[1] : 'main'
35
+ }, [basePath])
36
+
37
+ const branchBasePath = (basePath || '/').replace(/\/branch--[^/]*\/$/, '/')
38
+
39
+ return { branches, currentBranch, branchBasePath, gitUser }
40
+ }
41
+
42
+ export function useSwitchBranch(basePath, branchBasePath) {
43
+ const [switching, setSwitching] = useState(null)
44
+ const [switchError, setSwitchError] = useState(null)
45
+
46
+ const switchBranch = useCallback(async (branch, folder) => {
47
+ if (switching) return
48
+ setSwitching(branch)
49
+ setSwitchError(null)
50
+
51
+ if (!isLocalDev) {
52
+ // Prod: direct navigation
53
+ window.location.href = `${branchBasePath}${folder || (branch === 'main' ? '' : `branch--${branch}/`)}`
54
+ return
55
+ }
56
+
57
+ // Dev: call switch-branch API to spin up server
58
+ const apiBase = (basePath || '/').replace(/\/$/, '')
59
+ try {
60
+ const res = await fetch(`${apiBase}/_storyboard/switch-branch`, {
61
+ method: 'POST',
62
+ headers: { 'Content-Type': 'application/json' },
63
+ body: JSON.stringify({ branch }),
64
+ })
65
+ const data = await res.json()
66
+ if (res.ok && data.url) {
67
+ window.location.href = data.url
68
+ } else {
69
+ setSwitchError(data.error || 'Failed to switch')
70
+ setSwitching(null)
71
+ }
72
+ } catch (e) {
73
+ setSwitchError(e.message || 'Server not reachable')
74
+ setSwitching(null)
75
+ }
76
+ }, [basePath, branchBasePath, switching])
77
+
78
+ return { switching, switchError, switchBranch }
79
+ }