@dfosco/storyboard-react 4.1.0 → 4.2.0-beta.1

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 CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@dfosco/storyboard-react",
3
- "version": "4.1.0",
3
+ "version": "4.2.0-beta.1",
4
4
  "type": "module",
5
5
  "dependencies": {
6
6
  "@base-ui/react": "^1.4.0",
7
- "@dfosco/storyboard-core": "4.1.0",
8
- "@dfosco/tiny-canvas": "4.1.0",
7
+ "@dfosco/storyboard-core": "4.2.0-beta.1",
8
+ "@dfosco/tiny-canvas": "4.2.0-beta.1",
9
9
  "@neodrag/react": "^2.3.1",
10
10
  "glob": "^11.0.0",
11
11
  "jsonc-parser": "^3.3.1",
@@ -20,6 +20,7 @@ import {
20
20
  getTheme,
21
21
  isExcludedByRoute,
22
22
  } from '@dfosco/storyboard-core'
23
+ import { widgetTypes } from '../canvas/widgets/widgetConfig.js'
23
24
  import CreateDialog from './CreateDialog.jsx'
24
25
  import BranchBar from '../BranchBar/BranchBar.jsx'
25
26
  import AuthModal from '../AuthModal/AuthModal.jsx'
@@ -287,15 +288,78 @@ function buildDynamicSection(section, prefix, onNavigateToPage, onCreateAction)
287
288
  const isLocalDev = typeof window !== 'undefined' && window.__SB_LOCAL_DEV__ === true
288
289
  if (!isLocalDev) return null
289
290
  const createItems = [
290
- { id: 'create:canvas', children: 'New Canvas', keywords: ['create', 'canvas', 'new', 'board'], showType: false, onClick: () => onCreateAction?.('Canvas') },
291
- { id: 'create:prototype', children: 'New Prototype', keywords: ['create', 'prototype', 'new', 'page'], showType: false, onClick: () => onCreateAction?.('Prototype') },
292
- { id: 'create:component', children: 'New Component', keywords: ['create', 'component', 'new', 'story'], showType: false, onClick: () => onCreateAction?.('Component') },
293
- { id: 'create:flow', children: 'New Prototype Flow', keywords: ['create', 'flow', 'new', 'data'], showType: false, onClick: () => onCreateAction?.('Flow') },
294
- { id: 'create:page', children: 'New Prototype Page', keywords: ['create', 'page', 'new'], showType: false, onClick: () => onCreateAction?.('Page') },
291
+ { id: 'create:canvas', children: 'Canvas', keywords: ['create', 'canvas', 'new', 'board'], showType: false, onClick: () => onCreateAction?.('Canvas') },
292
+ { id: 'create:prototype', children: 'Prototype', keywords: ['create', 'prototype', 'new', 'page'], showType: false, onClick: () => onCreateAction?.('Prototype') },
293
+ { id: 'create:component', children: 'Component', keywords: ['create', 'component', 'new', 'story'], showType: false, onClick: () => onCreateAction?.('Component') },
294
+ { id: 'create:flow', children: 'Prototype Flow', keywords: ['create', 'flow', 'new', 'data'], showType: false, onClick: () => onCreateAction?.('Flow') },
295
+ { id: 'create:page', children: 'Prototype Page', keywords: ['create', 'page', 'new'], showType: false, onClick: () => onCreateAction?.('Page') },
295
296
  ]
296
297
  return { group: { heading: section.title, id: `cfg:${section.id}`, items: createItems } }
297
298
  }
298
299
 
300
+ // --- Create widget source (all canvas widget types) ---
301
+ if (section.source === 'create-widget') {
302
+ const isLocalDev = typeof window !== 'undefined' && window.__SB_LOCAL_DEV__ === true
303
+ if (!isLocalDev) return null
304
+ const isCanvasRoute = typeof window !== 'undefined' && window.location.pathname.includes('/canvas/')
305
+ if (!isCanvasRoute) return null
306
+ const items = Object.entries(widgetTypes).map(([type, def]) => ({
307
+ id: `create-widget:${type}`,
308
+ children: def.label,
309
+ keywords: ['add', 'widget', 'create', type, def.label.toLowerCase()],
310
+ showType: false,
311
+ onClick: () => {
312
+ document.dispatchEvent(new CustomEvent('storyboard:canvas:add-widget', { detail: { type } }))
313
+ },
314
+ }))
315
+ return { group: { heading: section.title, id: `cfg:${section.id}`, items } }
316
+ }
317
+
318
+ // --- Starred source (reads from viewfinder localStorage) ---
319
+ if (section.source === 'starred') {
320
+ const STARRED_KEY = 'sb-viewfinder-starred'
321
+ let starredIds = []
322
+ try { starredIds = JSON.parse(localStorage.getItem(STARRED_KEY)) || [] } catch {}
323
+ if (starredIds.length === 0) return null
324
+
325
+ const index = buildPrototypeIndex()
326
+ // Build a lookup map of all artifacts
327
+ const artifactMap = new Map()
328
+ const allProtos = [...index.prototypes]
329
+ for (const folder of index.folders) {
330
+ allProtos.push(...folder.prototypes)
331
+ if (folder.canvases) folder.canvases.forEach(c => artifactMap.set(`canvas:${c.dirName}`, { ...c, _type: 'canvas' }))
332
+ }
333
+ for (const c of index.canvases) artifactMap.set(`canvas:${c.dirName}`, { ...c, _type: 'canvas' })
334
+ for (const p of allProtos) artifactMap.set(`proto:${p.dirName}`, { ...p, _type: 'prototype' })
335
+
336
+ const items = []
337
+ for (const id of starredIds) {
338
+ const artifact = artifactMap.get(id)
339
+ if (!artifact) continue
340
+ const route = artifact._type === 'canvas'
341
+ ? `${prefix}/canvas/${artifact.dirName}`
342
+ : artifact.isExternal
343
+ ? artifact.externalUrl
344
+ : `${prefix}/${artifact.dirName}`
345
+ items.push({
346
+ id: `starred:${id}`,
347
+ children: artifact.name,
348
+ keywords: ['starred', 'star', artifact.name.toLowerCase()],
349
+ showType: false,
350
+ onClick: () => {
351
+ if (artifact.isExternal) {
352
+ window.open(route, '_blank')
353
+ } else {
354
+ window.location.href = route
355
+ }
356
+ },
357
+ })
358
+ }
359
+ if (items.length === 0) return null
360
+ return { group: { heading: section.title, id: `cfg:${section.id}`, items } }
361
+ }
362
+
299
363
  // --- Commands source (all registered toolbar actions) ---
300
364
  if (section.source === 'commands') {
301
365
  const mode = getCurrentMode() || 'default'
@@ -109,3 +109,8 @@ html[data-color-mode="dark"] .command-palette .border-b {
109
109
  .command-palette .command-palette-list-item .text-gray-500.text-sm {
110
110
  display: none !important;
111
111
  }
112
+
113
+ /* Medium weight for item text */
114
+ .command-palette .command-palette-list-item {
115
+ font-weight: 500 !important;
116
+ }