@dfosco/storyboard-react 4.0.0-beta.9 → 4.0.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/package.json +6 -3
- package/src/AuthModal/AuthModal.jsx +134 -0
- package/src/AuthModal/AuthModal.module.css +221 -0
- package/src/BranchBar/BranchBar.jsx +56 -0
- package/src/BranchBar/BranchBar.module.css +230 -0
- package/src/BranchBar/useBranches.js +79 -0
- package/src/CommandPalette/CommandPalette.jsx +936 -0
- package/src/CommandPalette/CreateDialog.jsx +219 -0
- package/src/CommandPalette/command-palette.css +111 -0
- package/src/Icon.jsx +180 -0
- package/src/Viewfinder.jsx +1104 -57
- package/src/Viewfinder.module.css +1107 -149
- package/src/canvas/CanvasControls.jsx +51 -2
- package/src/canvas/CanvasControls.module.css +31 -0
- package/src/canvas/CanvasPage.bridge.test.jsx +142 -19
- package/src/canvas/CanvasPage.dragdrop.test.jsx +346 -0
- package/src/canvas/CanvasPage.jsx +807 -251
- package/src/canvas/CanvasPage.module.css +98 -50
- package/src/canvas/CanvasPage.multiselect.test.jsx +13 -11
- package/src/canvas/CanvasToolbar.jsx +2 -2
- package/src/canvas/MarqueeOverlay.jsx +20 -0
- package/src/canvas/PageSelector.jsx +239 -0
- package/src/canvas/PageSelector.module.css +165 -0
- package/src/canvas/PageSelector.test.jsx +104 -0
- package/src/canvas/canvasApi.js +22 -8
- package/src/canvas/canvasTheme.js +96 -52
- package/src/canvas/componentIsolate.jsx +33 -7
- package/src/canvas/useCanvas.js +9 -8
- package/src/canvas/useCanvas.test.js +4 -4
- package/src/canvas/useMarqueeSelect.js +187 -0
- package/src/canvas/useMarqueeSelect.test.js +78 -0
- package/src/canvas/widgets/CodePenEmbed.jsx +292 -0
- package/src/canvas/widgets/CodePenEmbed.module.css +161 -0
- package/src/canvas/widgets/ComponentWidget.jsx +42 -10
- package/src/canvas/widgets/ComponentWidget.module.css +6 -5
- 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 +86 -5
- package/src/canvas/widgets/MarkdownBlock.module.css +64 -15
- package/src/canvas/widgets/PrototypeEmbed.jsx +96 -145
- 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 +277 -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 +2 -6
- 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 +138 -39
- 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 +145 -16
- package/src/hooks/useSceneData.js +4 -2
- package/src/hooks/useThemeState.js +61 -0
- package/src/hooks/useThemeState.test.js +66 -0
- package/src/index.js +10 -0
- package/src/story/StoryPage.jsx +117 -0
- package/src/story/StoryPage.module.css +18 -0
- package/src/vite/data-plugin.js +348 -66
- package/src/vite/data-plugin.test.js +405 -5
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useState, useRef, useEffect, useCallback } from 'react'
|
|
2
2
|
import { getMenuWidgetTypes } from './widgets/widgetConfig.js'
|
|
3
|
+
import { listStories, getStoryData } from '@dfosco/storyboard-core'
|
|
3
4
|
import styles from './CanvasControls.module.css'
|
|
4
5
|
|
|
5
6
|
const WIDGET_TYPES = getMenuWidgetTypes()
|
|
@@ -9,6 +10,7 @@ const WIDGET_TYPES = getMenuWidgetTypes()
|
|
|
9
10
|
*/
|
|
10
11
|
export default function CanvasControls({ onAddWidget }) {
|
|
11
12
|
const [menuOpen, setMenuOpen] = useState(false)
|
|
13
|
+
const [storyPicker, setStoryPicker] = useState(false)
|
|
12
14
|
const menuRef = useRef(null)
|
|
13
15
|
|
|
14
16
|
// Close menu on outside click
|
|
@@ -17,6 +19,7 @@ export default function CanvasControls({ onAddWidget }) {
|
|
|
17
19
|
function handlePointerDown(e) {
|
|
18
20
|
if (menuRef.current && !menuRef.current.contains(e.target)) {
|
|
19
21
|
setMenuOpen(false)
|
|
22
|
+
setStoryPicker(false)
|
|
20
23
|
}
|
|
21
24
|
}
|
|
22
25
|
document.addEventListener('pointerdown', handlePointerDown)
|
|
@@ -26,14 +29,23 @@ export default function CanvasControls({ onAddWidget }) {
|
|
|
26
29
|
const handleAddWidget = useCallback((type) => {
|
|
27
30
|
onAddWidget(type)
|
|
28
31
|
setMenuOpen(false)
|
|
32
|
+
setStoryPicker(false)
|
|
29
33
|
}, [onAddWidget])
|
|
30
34
|
|
|
35
|
+
const handleAddStory = useCallback((storyId) => {
|
|
36
|
+
document.dispatchEvent(new CustomEvent('storyboard:canvas:add-story-widget', { detail: { storyId } }))
|
|
37
|
+
setMenuOpen(false)
|
|
38
|
+
setStoryPicker(false)
|
|
39
|
+
}, [])
|
|
40
|
+
|
|
41
|
+
const storyNames = storyPicker ? listStories() : []
|
|
42
|
+
|
|
31
43
|
return (
|
|
32
44
|
<div className={styles.toolbar} role="toolbar" aria-label="Canvas controls">
|
|
33
45
|
<div ref={menuRef} className={styles.createGroup}>
|
|
34
46
|
<button
|
|
35
47
|
className={styles.btn}
|
|
36
|
-
onClick={() => setMenuOpen((v) => !v)}
|
|
48
|
+
onClick={() => { setMenuOpen((v) => !v); setStoryPicker(false) }}
|
|
37
49
|
aria-label="Add widget"
|
|
38
50
|
aria-expanded={menuOpen}
|
|
39
51
|
title="Add widget"
|
|
@@ -42,7 +54,7 @@ export default function CanvasControls({ onAddWidget }) {
|
|
|
42
54
|
<path d="M7.75 2a.75.75 0 0 1 .75.75V7h4.25a.75.75 0 0 1 0 1.5H8.5v4.25a.75.75 0 0 1-1.5 0V8.5H2.75a.75.75 0 0 1 0-1.5H7V2.75A.75.75 0 0 1 7.75 2Z" />
|
|
43
55
|
</svg>
|
|
44
56
|
</button>
|
|
45
|
-
{menuOpen && (
|
|
57
|
+
{menuOpen && !storyPicker && (
|
|
46
58
|
<div className={styles.menu} role="menu">
|
|
47
59
|
<div className={styles.menuLabel}>Add to canvas</div>
|
|
48
60
|
{WIDGET_TYPES.map((wt) => (
|
|
@@ -55,6 +67,43 @@ export default function CanvasControls({ onAddWidget }) {
|
|
|
55
67
|
{wt.label}
|
|
56
68
|
</button>
|
|
57
69
|
))}
|
|
70
|
+
<div className={styles.menuDivider} />
|
|
71
|
+
<button
|
|
72
|
+
className={styles.menuItem}
|
|
73
|
+
role="menuitem"
|
|
74
|
+
onClick={() => setStoryPicker(true)}
|
|
75
|
+
>
|
|
76
|
+
📖 Component
|
|
77
|
+
</button>
|
|
78
|
+
</div>
|
|
79
|
+
)}
|
|
80
|
+
{menuOpen && storyPicker && (
|
|
81
|
+
<div className={styles.menu} role="menu">
|
|
82
|
+
<div className={styles.menuLabel}>
|
|
83
|
+
<button
|
|
84
|
+
className={styles.backBtn}
|
|
85
|
+
onClick={() => setStoryPicker(false)}
|
|
86
|
+
aria-label="Back"
|
|
87
|
+
>←</button>
|
|
88
|
+
Select component
|
|
89
|
+
</div>
|
|
90
|
+
{storyNames.length === 0 && (
|
|
91
|
+
<div className={styles.menuEmpty}>No stories found</div>
|
|
92
|
+
)}
|
|
93
|
+
{storyNames.map((name) => {
|
|
94
|
+
const story = getStoryData(name)
|
|
95
|
+
return (
|
|
96
|
+
<button
|
|
97
|
+
key={name}
|
|
98
|
+
className={styles.menuItem}
|
|
99
|
+
role="menuitem"
|
|
100
|
+
onClick={() => handleAddStory(name)}
|
|
101
|
+
>
|
|
102
|
+
{name}
|
|
103
|
+
{story?._route && <span className={styles.menuHint}>{story._route}</span>}
|
|
104
|
+
</button>
|
|
105
|
+
)
|
|
106
|
+
})}
|
|
58
107
|
</div>
|
|
59
108
|
)}
|
|
60
109
|
</div>
|
|
@@ -102,3 +102,34 @@
|
|
|
102
102
|
.menuItem:hover {
|
|
103
103
|
background: var(--bgColor-muted, #f6f8fa);
|
|
104
104
|
}
|
|
105
|
+
|
|
106
|
+
.menuDivider {
|
|
107
|
+
height: 1px;
|
|
108
|
+
margin: 4px 8px;
|
|
109
|
+
background: var(--borderColor-muted, rgba(0, 0, 0, 0.1));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.menuHint {
|
|
113
|
+
font-size: 11px;
|
|
114
|
+
color: var(--fgColor-muted, #656d76);
|
|
115
|
+
margin-left: 8px;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.menuEmpty {
|
|
119
|
+
padding: 8px 10px;
|
|
120
|
+
font-size: 12px;
|
|
121
|
+
color: var(--fgColor-muted, #656d76);
|
|
122
|
+
font-style: italic;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.backBtn {
|
|
126
|
+
all: unset;
|
|
127
|
+
cursor: pointer;
|
|
128
|
+
margin-right: 4px;
|
|
129
|
+
font-size: 13px;
|
|
130
|
+
color: var(--fgColor-muted, #656d76);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.backBtn:hover {
|
|
134
|
+
color: var(--fgColor-default, #1f2328);
|
|
135
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { fireEvent, render, screen, act } from '@testing-library/react'
|
|
1
|
+
import { fireEvent, render, screen, act, waitFor } from '@testing-library/react'
|
|
2
2
|
import CanvasPage from './CanvasPage.jsx'
|
|
3
3
|
import { getCanvasPrimerAttrs, getCanvasThemeVars } from './canvasTheme.js'
|
|
4
|
-
import { updateCanvas } from './canvasApi.js'
|
|
4
|
+
import { addWidget, checkGitHubCliAvailable, fetchGitHubEmbed, updateCanvas } from './canvasApi.js'
|
|
5
5
|
|
|
6
6
|
vi.mock('@dfosco/tiny-canvas', () => ({
|
|
7
7
|
Canvas: ({ children, onDragEnd }) => (
|
|
@@ -77,6 +77,8 @@ vi.mock('./widgets/figmaUrl.js', () => ({
|
|
|
77
77
|
|
|
78
78
|
vi.mock('./canvasApi.js', () => ({
|
|
79
79
|
addWidget: vi.fn(),
|
|
80
|
+
checkGitHubCliAvailable: vi.fn(),
|
|
81
|
+
fetchGitHubEmbed: vi.fn(),
|
|
80
82
|
updateCanvas: vi.fn(() => Promise.resolve({ success: true })),
|
|
81
83
|
removeWidget: vi.fn(),
|
|
82
84
|
uploadImage: vi.fn(),
|
|
@@ -94,9 +96,26 @@ vi.mock('./useUndoRedo.js', () => ({
|
|
|
94
96
|
}))
|
|
95
97
|
|
|
96
98
|
describe('CanvasPage canvas bridge', () => {
|
|
99
|
+
function dispatchTextPaste(text) {
|
|
100
|
+
const event = new Event('paste', { bubbles: true, cancelable: true })
|
|
101
|
+
Object.defineProperty(event, 'clipboardData', {
|
|
102
|
+
value: {
|
|
103
|
+
getData: (type) => (type === 'text/plain' ? text : ''),
|
|
104
|
+
items: [],
|
|
105
|
+
},
|
|
106
|
+
})
|
|
107
|
+
document.dispatchEvent(event)
|
|
108
|
+
}
|
|
109
|
+
|
|
97
110
|
beforeEach(() => {
|
|
98
111
|
delete window.__storyboardCanvasBridgeState
|
|
99
112
|
vi.clearAllMocks()
|
|
113
|
+
addWidget.mockResolvedValue({
|
|
114
|
+
success: true,
|
|
115
|
+
widget: { id: 'widget-link', type: 'link-preview', position: { x: 0, y: 0 }, props: {} },
|
|
116
|
+
})
|
|
117
|
+
checkGitHubCliAvailable.mockResolvedValue({ available: true })
|
|
118
|
+
fetchGitHubEmbed.mockResolvedValue({ success: false })
|
|
100
119
|
})
|
|
101
120
|
|
|
102
121
|
it('publishes bridge state and responds to status requests', () => {
|
|
@@ -105,11 +124,11 @@ describe('CanvasPage canvas bridge', () => {
|
|
|
105
124
|
document.addEventListener('storyboard:canvas:mounted', mountedHandler)
|
|
106
125
|
document.addEventListener('storyboard:canvas:status', statusHandler)
|
|
107
126
|
|
|
108
|
-
const { unmount } = render(<CanvasPage
|
|
127
|
+
const { unmount } = render(<CanvasPage canvasId="design-overview" />)
|
|
109
128
|
|
|
110
129
|
expect(window.__storyboardCanvasBridgeState).toEqual({
|
|
111
130
|
active: true,
|
|
112
|
-
|
|
131
|
+
canvasId: 'design-overview',
|
|
113
132
|
zoom: 100,
|
|
114
133
|
})
|
|
115
134
|
expect(mountedHandler).toHaveBeenCalled()
|
|
@@ -118,7 +137,7 @@ describe('CanvasPage canvas bridge', () => {
|
|
|
118
137
|
expect(statusHandler).toHaveBeenCalled()
|
|
119
138
|
expect(statusHandler.mock.calls.at(-1)?.[0]?.detail).toEqual({
|
|
120
139
|
active: true,
|
|
121
|
-
|
|
140
|
+
canvasId: 'design-overview',
|
|
122
141
|
zoom: 100,
|
|
123
142
|
})
|
|
124
143
|
|
|
@@ -132,22 +151,88 @@ describe('CanvasPage canvas bridge', () => {
|
|
|
132
151
|
const unmountedHandler = vi.fn()
|
|
133
152
|
document.addEventListener('storyboard:canvas:unmounted', unmountedHandler)
|
|
134
153
|
|
|
135
|
-
const { unmount } = render(<CanvasPage
|
|
154
|
+
const { unmount } = render(<CanvasPage canvasId="design-overview" />)
|
|
136
155
|
unmount()
|
|
137
156
|
|
|
138
157
|
expect(unmountedHandler).toHaveBeenCalled()
|
|
139
158
|
expect(window.__storyboardCanvasBridgeState).toEqual({
|
|
140
159
|
active: false,
|
|
141
|
-
|
|
160
|
+
canvasId: '',
|
|
142
161
|
zoom: 100,
|
|
143
162
|
})
|
|
144
163
|
|
|
145
164
|
document.removeEventListener('storyboard:canvas:unmounted', unmountedHandler)
|
|
146
165
|
})
|
|
147
166
|
|
|
148
|
-
it
|
|
167
|
+
it('shows gh install banner when gh is unavailable during GitHub URL paste', async () => {
|
|
168
|
+
checkGitHubCliAvailable.mockResolvedValue({
|
|
169
|
+
available: false,
|
|
170
|
+
installUrl: 'https://github.com/cli/cli',
|
|
171
|
+
})
|
|
172
|
+
|
|
149
173
|
render(<CanvasPage name="design-overview" />)
|
|
150
174
|
|
|
175
|
+
await act(async () => {
|
|
176
|
+
dispatchTextPaste('https://github.com/dfosco/storyboard/issues/42')
|
|
177
|
+
await Promise.resolve()
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
await waitFor(() => {
|
|
181
|
+
expect(addWidget).toHaveBeenCalled()
|
|
182
|
+
})
|
|
183
|
+
expect(fetchGitHubEmbed).not.toHaveBeenCalled()
|
|
184
|
+
expect(screen.getByRole('link', { name: 'Install GitHub CLI' })).toHaveAttribute(
|
|
185
|
+
'href',
|
|
186
|
+
'https://github.com/cli/cli',
|
|
187
|
+
)
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
it('hydrates GitHub metadata when gh is available during paste', async () => {
|
|
191
|
+
checkGitHubCliAvailable.mockResolvedValue({ available: true })
|
|
192
|
+
fetchGitHubEmbed.mockResolvedValue({
|
|
193
|
+
success: true,
|
|
194
|
+
snapshot: {
|
|
195
|
+
kind: 'issue',
|
|
196
|
+
parentKind: 'issue',
|
|
197
|
+
context: 'GitHub · dfosco/storyboard · Issue #42',
|
|
198
|
+
title: '#42 Ship GitHub embeds',
|
|
199
|
+
body: 'Details from GitHub',
|
|
200
|
+
authors: ['dfosco'],
|
|
201
|
+
createdAt: '2026-01-01T00:00:00Z',
|
|
202
|
+
updatedAt: '2026-01-02T00:00:00Z',
|
|
203
|
+
},
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
render(<CanvasPage name="design-overview" />)
|
|
207
|
+
|
|
208
|
+
await act(async () => {
|
|
209
|
+
dispatchTextPaste('https://github.com/dfosco/storyboard/issues/42')
|
|
210
|
+
await Promise.resolve()
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
await waitFor(() => {
|
|
214
|
+
expect(fetchGitHubEmbed).toHaveBeenCalledWith('https://github.com/dfosco/storyboard/issues/42')
|
|
215
|
+
})
|
|
216
|
+
expect(addWidget).toHaveBeenCalledWith(
|
|
217
|
+
'design-overview',
|
|
218
|
+
expect.objectContaining({
|
|
219
|
+
type: 'link-preview',
|
|
220
|
+
props: expect.objectContaining({
|
|
221
|
+
title: '#42 Ship GitHub embeds',
|
|
222
|
+
width: 580,
|
|
223
|
+
height: 400,
|
|
224
|
+
github: expect.objectContaining({
|
|
225
|
+
context: 'GitHub · dfosco/storyboard · Issue #42',
|
|
226
|
+
body: 'Details from GitHub',
|
|
227
|
+
}),
|
|
228
|
+
}),
|
|
229
|
+
}),
|
|
230
|
+
)
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
it.skip('persists dragged JSON widgets and JSX sources to canvas JSONL via update API', async () => {
|
|
234
|
+
render(<CanvasPage canvasId="design-overview" />)
|
|
235
|
+
|
|
151
236
|
fireEvent.click(screen.getByTestId('drag-widget'))
|
|
152
237
|
// Flush the promise-based write queue
|
|
153
238
|
await act(async () => { await new Promise((r) => setTimeout(r, 0)) })
|
|
@@ -179,7 +264,7 @@ describe('CanvasPage canvas bridge', () => {
|
|
|
179
264
|
})
|
|
180
265
|
|
|
181
266
|
it.skip('clamps negative drag positions to zero', async () => {
|
|
182
|
-
render(<CanvasPage
|
|
267
|
+
render(<CanvasPage canvasId="design-overview" />)
|
|
183
268
|
|
|
184
269
|
fireEvent.click(screen.getByTestId('drag-widget-negative'))
|
|
185
270
|
await act(async () => { await new Promise((r) => setTimeout(r, 0)) })
|
|
@@ -198,17 +283,40 @@ describe('CanvasPage canvas bridge', () => {
|
|
|
198
283
|
})
|
|
199
284
|
|
|
200
285
|
describe('getCanvasThemeVars', () => {
|
|
201
|
-
it('returns
|
|
286
|
+
it('returns correct tokens for each theme', () => {
|
|
202
287
|
expect(getCanvasThemeVars('light')['--sb--canvas-bg']).toBe('#f6f8fa')
|
|
203
288
|
expect(getCanvasThemeVars('light')['--tc-bg-muted']).toBe('#f6f8fa')
|
|
204
|
-
expect(getCanvasThemeVars('dark')['--sb--canvas-bg']).toBe('#
|
|
205
|
-
expect(getCanvasThemeVars('dark')['--bgColor-muted']).toBe('#
|
|
206
|
-
expect(getCanvasThemeVars('dark')['--tc-bg-muted']).toBe('#
|
|
207
|
-
expect(getCanvasThemeVars('dark_dimmed')['--sb--canvas-bg']).toBe('#
|
|
208
|
-
expect(getCanvasThemeVars('dark_dimmed')['--bgColor-muted']).toBe('#
|
|
209
|
-
expect(getCanvasThemeVars('dark_dimmed')['--tc-bg-muted']).toBe('#
|
|
210
|
-
expect(getCanvasThemeVars('dark_dimmed')['--tc-dot-color']).toBe('rgba(
|
|
211
|
-
expect(getCanvasThemeVars('dark_dimmed')['--overlay-backdrop-bgColor']).toBe('rgba(
|
|
289
|
+
expect(getCanvasThemeVars('dark')['--sb--canvas-bg']).toBe('#151b23')
|
|
290
|
+
expect(getCanvasThemeVars('dark')['--bgColor-muted']).toBe('#151b23')
|
|
291
|
+
expect(getCanvasThemeVars('dark')['--tc-bg-muted']).toBe('#151b23')
|
|
292
|
+
expect(getCanvasThemeVars('dark_dimmed')['--sb--canvas-bg']).toBe('#262c36')
|
|
293
|
+
expect(getCanvasThemeVars('dark_dimmed')['--bgColor-muted']).toBe('#262c36')
|
|
294
|
+
expect(getCanvasThemeVars('dark_dimmed')['--tc-bg-muted']).toBe('#262c36')
|
|
295
|
+
expect(getCanvasThemeVars('dark_dimmed')['--tc-dot-color']).toBe('rgba(209, 215, 224, 0.18)')
|
|
296
|
+
expect(getCanvasThemeVars('dark_dimmed')['--overlay-backdrop-bgColor']).toBe('rgba(209, 215, 224, 0.18)')
|
|
297
|
+
})
|
|
298
|
+
|
|
299
|
+
it('returns distinct values for dark_high_contrast', () => {
|
|
300
|
+
const vars = getCanvasThemeVars('dark_high_contrast')
|
|
301
|
+
expect(vars['--bgColor-default']).toBe('#010409')
|
|
302
|
+
expect(vars['--borderColor-default']).toBe('#b7bdc8')
|
|
303
|
+
expect(vars['--fgColor-default']).toBe('#ffffff')
|
|
304
|
+
})
|
|
305
|
+
|
|
306
|
+
it('returns distinct values for dark_colorblind', () => {
|
|
307
|
+
const vars = getCanvasThemeVars('dark_colorblind')
|
|
308
|
+
expect(vars['--bgColor-default']).toBe('#0d1117')
|
|
309
|
+
expect(vars['--fgColor-muted']).toBe('#9198a1')
|
|
310
|
+
})
|
|
311
|
+
|
|
312
|
+
it('returns distinct values for light_colorblind', () => {
|
|
313
|
+
const vars = getCanvasThemeVars('light_colorblind')
|
|
314
|
+
expect(vars['--bgColor-default']).toBe('#ffffff')
|
|
315
|
+
expect(vars['--fgColor-muted']).toBe('#59636e')
|
|
316
|
+
})
|
|
317
|
+
|
|
318
|
+
it('falls back to light for unknown themes', () => {
|
|
319
|
+
expect(getCanvasThemeVars('unknown')).toEqual(getCanvasThemeVars('light'))
|
|
212
320
|
})
|
|
213
321
|
})
|
|
214
322
|
|
|
@@ -219,6 +327,11 @@ describe('getCanvasPrimerAttrs', () => {
|
|
|
219
327
|
'data-dark-theme': 'dark',
|
|
220
328
|
'data-light-theme': 'light',
|
|
221
329
|
})
|
|
330
|
+
expect(getCanvasPrimerAttrs('light_colorblind')).toEqual({
|
|
331
|
+
'data-color-mode': 'light',
|
|
332
|
+
'data-dark-theme': 'dark',
|
|
333
|
+
'data-light-theme': 'light_colorblind',
|
|
334
|
+
})
|
|
222
335
|
expect(getCanvasPrimerAttrs('dark')).toEqual({
|
|
223
336
|
'data-color-mode': 'dark',
|
|
224
337
|
'data-dark-theme': 'dark',
|
|
@@ -229,6 +342,16 @@ describe('getCanvasPrimerAttrs', () => {
|
|
|
229
342
|
'data-dark-theme': 'dark_dimmed',
|
|
230
343
|
'data-light-theme': 'light',
|
|
231
344
|
})
|
|
345
|
+
expect(getCanvasPrimerAttrs('dark_high_contrast')).toEqual({
|
|
346
|
+
'data-color-mode': 'dark',
|
|
347
|
+
'data-dark-theme': 'dark_high_contrast',
|
|
348
|
+
'data-light-theme': 'light',
|
|
349
|
+
})
|
|
350
|
+
expect(getCanvasPrimerAttrs('dark_colorblind')).toEqual({
|
|
351
|
+
'data-color-mode': 'dark',
|
|
352
|
+
'data-dark-theme': 'dark_colorblind',
|
|
353
|
+
'data-light-theme': 'light',
|
|
354
|
+
})
|
|
232
355
|
})
|
|
233
356
|
})
|
|
234
357
|
|
|
@@ -243,7 +366,7 @@ describe('canvas target fallback', () => {
|
|
|
243
366
|
localStorage.setItem('sb-color-scheme', 'dark')
|
|
244
367
|
document.documentElement.setAttribute('data-sb-canvas-theme', 'dark')
|
|
245
368
|
|
|
246
|
-
render(<CanvasPage
|
|
369
|
+
render(<CanvasPage canvasId="design-overview" />)
|
|
247
370
|
|
|
248
371
|
const scroll = document.querySelector('[data-storyboard-canvas-scroll]')
|
|
249
372
|
const jsxWidget = document.getElementById('jsx-PrimaryButtons')
|