@dfosco/storyboard-react 4.0.0-beta.4 → 4.0.0-beta.41
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/package.json +9 -4
- package/src/Icon.jsx +179 -0
- package/src/Viewfinder.jsx +1030 -57
- package/src/Viewfinder.module.css +1524 -155
- package/src/canvas/CanvasControls.jsx +51 -2
- package/src/canvas/CanvasControls.module.css +31 -0
- package/src/canvas/CanvasPage.bridge.test.jsx +95 -10
- package/src/canvas/CanvasPage.dragdrop.test.jsx +346 -0
- package/src/canvas/CanvasPage.jsx +843 -301
- package/src/canvas/CanvasPage.module.css +73 -50
- package/src/canvas/CanvasPage.multiselect.test.jsx +13 -11
- package/src/canvas/CanvasToolbar.jsx +2 -2
- package/src/canvas/ComponentErrorBoundary.jsx +50 -0
- package/src/canvas/PageSelector.jsx +198 -0
- package/src/canvas/PageSelector.module.css +158 -0
- package/src/canvas/PageSelector.test.jsx +104 -0
- package/src/canvas/canvasApi.js +22 -8
- package/src/canvas/canvasReloadGuard.js +37 -0
- package/src/canvas/canvasReloadGuard.test.js +27 -0
- package/src/canvas/componentIsolate.jsx +135 -0
- package/src/canvas/useCanvas.js +15 -10
- package/src/canvas/widgets/CodePenEmbed.jsx +292 -0
- package/src/canvas/widgets/CodePenEmbed.module.css +161 -0
- package/src/canvas/widgets/ComponentWidget.jsx +82 -9
- package/src/canvas/widgets/ComponentWidget.module.css +14 -6
- package/src/canvas/widgets/FigmaEmbed.jsx +110 -24
- package/src/canvas/widgets/FigmaEmbed.module.css +21 -7
- package/src/canvas/widgets/LinkPreview.jsx +297 -11
- package/src/canvas/widgets/LinkPreview.module.css +386 -18
- package/src/canvas/widgets/LinkPreview.test.jsx +193 -0
- package/src/canvas/widgets/MarkdownBlock.jsx +95 -21
- package/src/canvas/widgets/MarkdownBlock.module.css +133 -2
- package/src/canvas/widgets/MarkdownBlock.test.jsx +39 -0
- package/src/canvas/widgets/PrototypeEmbed.jsx +95 -144
- package/src/canvas/widgets/PrototypeEmbed.module.css +74 -4
- package/src/canvas/widgets/StickyNote.module.css +5 -0
- package/src/canvas/widgets/StickyNote.test.jsx +9 -9
- package/src/canvas/widgets/StoryWidget.jsx +276 -0
- package/src/canvas/widgets/StoryWidget.module.css +211 -0
- package/src/canvas/widgets/WidgetChrome.jsx +76 -20
- package/src/canvas/widgets/WidgetChrome.module.css +4 -7
- package/src/canvas/widgets/WidgetWrapper.module.css +2 -0
- package/src/canvas/widgets/codepenUrl.js +75 -0
- package/src/canvas/widgets/codepenUrl.test.js +76 -0
- package/src/canvas/widgets/embedInteraction.test.jsx +235 -0
- package/src/canvas/widgets/embedOverlay.module.css +35 -0
- package/src/canvas/widgets/embedTheme.js +56 -0
- package/src/canvas/widgets/githubUrl.js +82 -0
- package/src/canvas/widgets/githubUrl.test.js +74 -0
- package/src/canvas/widgets/iframeDevLogs.js +49 -0
- package/src/canvas/widgets/iframeDevLogs.test.jsx +81 -0
- package/src/canvas/widgets/index.js +4 -0
- package/src/canvas/widgets/pasteRules.js +295 -0
- package/src/canvas/widgets/pasteRules.test.js +474 -0
- package/src/canvas/widgets/snapshotDisplay.test.jsx +259 -0
- package/src/canvas/widgets/widgetConfig.js +16 -5
- package/src/canvas/widgets/widgetConfig.test.js +34 -12
- package/src/context.jsx +141 -16
- package/src/hooks/useSceneData.js +4 -2
- package/src/story/StoryPage.jsx +117 -0
- package/src/story/StoryPage.module.css +18 -0
- package/src/vite/data-plugin.js +375 -57
- package/src/vite/data-plugin.test.js +405 -5
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StoryPage — renders a .story.jsx module at its own route.
|
|
3
|
+
*
|
|
4
|
+
* Renders only the bare component(s) with no layout chrome.
|
|
5
|
+
* When ?export=ExportName is present, renders that single export.
|
|
6
|
+
* Without ?export, renders all named exports stacked.
|
|
7
|
+
*/
|
|
8
|
+
import { useState, useEffect, useMemo } from 'react'
|
|
9
|
+
import { useLocation } from 'react-router-dom'
|
|
10
|
+
import { getStoryData } from '@dfosco/storyboard-core'
|
|
11
|
+
import { ThemeProvider, BaseStyles } from '@primer/react'
|
|
12
|
+
import styles from './StoryPage.module.css'
|
|
13
|
+
|
|
14
|
+
function StoryErrorFallback({ name, error }) {
|
|
15
|
+
return (
|
|
16
|
+
<div className={styles.error}>
|
|
17
|
+
<strong>{name}</strong>
|
|
18
|
+
<span>{String(error?.message || error)}</span>
|
|
19
|
+
</div>
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default function StoryPage({ name }) {
|
|
24
|
+
const location = useLocation()
|
|
25
|
+
const searchParams = new URLSearchParams(location.search)
|
|
26
|
+
const exportFilter = searchParams.get('export')
|
|
27
|
+
const isEmbed = searchParams.has('_sb_embed')
|
|
28
|
+
|
|
29
|
+
const story = useMemo(() => getStoryData(name), [name])
|
|
30
|
+
const [exports, setExports] = useState(null)
|
|
31
|
+
const [error, setError] = useState(null)
|
|
32
|
+
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
if (!story?._storyImport) {
|
|
35
|
+
Promise.resolve().then(() => setError(`Story "${name}" not found or missing import`))
|
|
36
|
+
return
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
let cancelled = false
|
|
40
|
+
story._storyImport()
|
|
41
|
+
.then((mod) => {
|
|
42
|
+
if (cancelled) return
|
|
43
|
+
const namedExports = {}
|
|
44
|
+
for (const [key, value] of Object.entries(mod)) {
|
|
45
|
+
if (key !== 'default' && typeof value === 'function') {
|
|
46
|
+
namedExports[key] = value
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
setExports(namedExports)
|
|
50
|
+
setError(null)
|
|
51
|
+
})
|
|
52
|
+
.catch((err) => {
|
|
53
|
+
if (cancelled) return
|
|
54
|
+
setError(`Failed to load story "${name}": ${err.message || err}`)
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
return () => { cancelled = true }
|
|
58
|
+
}, [name, story])
|
|
59
|
+
|
|
60
|
+
// Signal snapshot-ready after story renders in embed mode.
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
if (!isEmbed || !exports || window.parent === window) return
|
|
63
|
+
document.fonts.ready.then(() => {
|
|
64
|
+
requestAnimationFrame(() => requestAnimationFrame(() => {
|
|
65
|
+
window.__sbSnapshotReady?.()
|
|
66
|
+
}))
|
|
67
|
+
})
|
|
68
|
+
}, [isEmbed, exports])
|
|
69
|
+
|
|
70
|
+
if (error) {
|
|
71
|
+
return (
|
|
72
|
+
<StoryErrorFallback name={name} error={error} />
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (!exports) {
|
|
77
|
+
if (isEmbed) return null
|
|
78
|
+
return (
|
|
79
|
+
<div className={styles.loading}>Loading story…</div>
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Single export mode
|
|
84
|
+
if (exportFilter) {
|
|
85
|
+
const Component = exports[exportFilter]
|
|
86
|
+
if (!Component) {
|
|
87
|
+
return (
|
|
88
|
+
<StoryErrorFallback
|
|
89
|
+
name={`${name}/${exportFilter}`}
|
|
90
|
+
error={`Export "${exportFilter}" not found in story "${name}"`}
|
|
91
|
+
/>
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
<ThemeProvider colorMode="day">
|
|
97
|
+
<BaseStyles>
|
|
98
|
+
<Component />
|
|
99
|
+
</BaseStyles>
|
|
100
|
+
</ThemeProvider>
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// All exports — render each component bare
|
|
105
|
+
const exportNames = Object.keys(exports)
|
|
106
|
+
|
|
107
|
+
return (
|
|
108
|
+
<ThemeProvider colorMode="day">
|
|
109
|
+
<BaseStyles>
|
|
110
|
+
{exportNames.map((exportName) => {
|
|
111
|
+
const Component = exports[exportName]
|
|
112
|
+
return <Component key={exportName} />
|
|
113
|
+
})}
|
|
114
|
+
</BaseStyles>
|
|
115
|
+
</ThemeProvider>
|
|
116
|
+
)
|
|
117
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
.loading {
|
|
2
|
+
display: flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
justify-content: center;
|
|
5
|
+
padding: 3rem;
|
|
6
|
+
color: var(--fgColor-muted, #656d76);
|
|
7
|
+
font-size: 0.875rem;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.error {
|
|
11
|
+
display: flex;
|
|
12
|
+
flex-direction: column;
|
|
13
|
+
gap: 4px;
|
|
14
|
+
padding: 1rem;
|
|
15
|
+
color: var(--fgColor-danger, #cf222e);
|
|
16
|
+
font-size: 0.875rem;
|
|
17
|
+
line-height: 1.5;
|
|
18
|
+
}
|