@dfosco/storyboard-core 4.2.5 → 4.2.6

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@dfosco/storyboard-core",
3
- "version": "4.2.5",
3
+ "version": "4.2.6",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "bin": {
package/src/CoreUIBar.jsx CHANGED
@@ -147,6 +147,9 @@ export default function CoreUIBar({ basePath = '/', toolbarConfig, customHandler
147
147
  const [visible, setVisible] = useState(
148
148
  () => !document.documentElement.classList.contains('storyboard-chrome-hidden')
149
149
  )
150
+ const [completelyHidden, setCompletelyHidden] = useState(
151
+ () => document.documentElement.classList.contains('storyboard-chrome-completely-hidden')
152
+ )
150
153
  const [toolComponents, setToolComponents] = useState({})
151
154
  const [toolData, setToolData] = useState({})
152
155
  const [navVersion, setNavVersion] = useState(0)
@@ -338,10 +341,25 @@ export default function CoreUIBar({ basePath = '/', toolbarConfig, customHandler
338
341
  setVisible((v) => {
339
342
  const next = !v
340
343
  document.documentElement.classList.toggle('storyboard-chrome-hidden', !next)
344
+ // Always clear completely-hidden when toggling via cmd+.
345
+ document.documentElement.classList.remove('storyboard-chrome-completely-hidden')
341
346
  return next
342
347
  })
343
348
  }, [])
344
349
 
350
+ const toggleCompletelyHidden = useCallback(() => {
351
+ const isAnyHidden = document.documentElement.classList.contains('storyboard-chrome-hidden')
352
+ if (isAnyHidden) {
353
+ document.documentElement.classList.remove('storyboard-chrome-hidden')
354
+ document.documentElement.classList.remove('storyboard-chrome-completely-hidden')
355
+ setVisible(true)
356
+ } else {
357
+ document.documentElement.classList.add('storyboard-chrome-hidden')
358
+ document.documentElement.classList.add('storyboard-chrome-completely-hidden')
359
+ setVisible(false)
360
+ }
361
+ }, [])
362
+
345
363
  function showFlowInfoDialog(name, json, error) {
346
364
  setFlowName(name)
347
365
  setFlowJson(json)
@@ -497,13 +515,15 @@ export default function CoreUIBar({ basePath = '/', toolbarConfig, customHandler
497
515
 
498
516
  setRoutingBasePath(basePath)
499
517
 
500
- // Sync visible state when storyboard-chrome-hidden is toggled externally
518
+ // Sync visible + completelyHidden state when classes are toggled externally
501
519
  const chromeObserver = new MutationObserver(() => {
502
520
  const hidden = document.documentElement.classList.contains('storyboard-chrome-hidden')
521
+ const fully = document.documentElement.classList.contains('storyboard-chrome-completely-hidden')
503
522
  setVisible((v) => {
504
523
  if (v === !hidden) return v
505
524
  return !hidden
506
525
  })
526
+ setCompletelyHidden(fully)
507
527
  })
508
528
  chromeObserver.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] })
509
529
 
@@ -690,10 +710,21 @@ export default function CoreUIBar({ basePath = '/', toolbarConfig, customHandler
690
710
  function handleKeydown(e) {
691
711
  const hideKey = shortcutsConfig.hideChrome?.key || '.'
692
712
 
693
- if (e.key === hideKey && (e.metaKey || e.ctrlKey)) {
694
- e.preventDefault()
695
- toggleToolsVisibility()
713
+ if ((e.metaKey || e.ctrlKey) && !e.shiftKey) {
714
+ // Alt+Cmd+. — completely hide (use e.code since alt changes e.key on macOS)
715
+ if (e.altKey && e.code === 'Period') {
716
+ e.preventDefault()
717
+ toggleCompletelyHidden()
718
+ return
719
+ }
720
+ // Cmd+. — regular hide/show
721
+ if (!e.altKey && e.key === hideKey) {
722
+ e.preventDefault()
723
+ toggleToolsVisibility()
724
+ return
725
+ }
696
726
  }
727
+
697
728
  for (const menu of cleanedMenus) {
698
729
  const shortcut = menu.shortcut
699
730
  if (!shortcut?.key) continue
@@ -711,14 +742,14 @@ export default function CoreUIBar({ basePath = '/', toolbarConfig, customHandler
711
742
 
712
743
  window.addEventListener('keydown', handleKeydown)
713
744
  return () => window.removeEventListener('keydown', handleKeydown)
714
- }, [shortcutsConfig, cleanedMenus, toggleToolsVisibility])
745
+ }, [shortcutsConfig, cleanedMenus, toggleToolsVisibility, toggleCompletelyHidden])
715
746
 
716
747
  if (isEmbed) return null
717
748
 
718
749
  return (
719
750
  <>
720
751
  {/* Canvas toolbar */}
721
- {canvasActive && canvasMenus.length > 0 && (
752
+ {canvasActive && !completelyHidden && canvasMenus.length > 0 && (
722
753
  <div
723
754
  className="fixed bottom-6 left-6 z-[9999] font-sans flex items-center gap-3"
724
755
  role="toolbar"
@@ -2,6 +2,7 @@
2
2
  * HideChromeTrigger — toolbar button that toggles toolbar/branch bar visibility.
3
3
  * Always visible (even in hide mode). Uses the lightbulb icon.
4
4
  * In hide mode: goes 50% opacity.
5
+ * In completely-hidden mode: not rendered at all.
5
6
  */
6
7
 
7
8
  import { useState, useEffect, useCallback } from 'react'
@@ -12,10 +13,14 @@ export default function HideChromeTrigger({ config = {}, tabindex }) {
12
13
  const [hidden, setHidden] = useState(
13
14
  () => document.documentElement.classList.contains('storyboard-chrome-hidden')
14
15
  )
16
+ const [completelyHidden, setCompletelyHidden] = useState(
17
+ () => document.documentElement.classList.contains('storyboard-chrome-completely-hidden')
18
+ )
15
19
 
16
20
  useEffect(() => {
17
21
  const observer = new MutationObserver(() => {
18
22
  setHidden(document.documentElement.classList.contains('storyboard-chrome-hidden'))
23
+ setCompletelyHidden(document.documentElement.classList.contains('storyboard-chrome-completely-hidden'))
19
24
  })
20
25
  observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] })
21
26
  return () => observer.disconnect()
@@ -23,8 +28,11 @@ export default function HideChromeTrigger({ config = {}, tabindex }) {
23
28
 
24
29
  const toggle = useCallback(() => {
25
30
  document.documentElement.classList.toggle('storyboard-chrome-hidden')
31
+ document.documentElement.classList.remove('storyboard-chrome-completely-hidden')
26
32
  }, [])
27
33
 
34
+ if (completelyHidden) return null
35
+
28
36
  return (
29
37
  <span style={{ opacity: hidden ? 0.5 : 1, transition: 'opacity 0.15s' }}>
30
38
  <TriggerButton
@@ -28,6 +28,7 @@ import {
28
28
  let _mounted = false
29
29
 
30
30
  const CHROME_HIDDEN_KEY = 'sb-chrome-hidden'
31
+ const CHROME_COMPLETELY_HIDDEN_KEY = 'sb-chrome-completely-hidden'
31
32
 
32
33
  /**
33
34
  * Migrate localStorage keys renamed in 4.3.0.
@@ -54,20 +55,26 @@ function migrateLocalStorageKeys() {
54
55
  function applyEarlyChromeState() {
55
56
  if (typeof document === 'undefined' || typeof localStorage === 'undefined') return
56
57
  const hidden = localStorage.getItem(CHROME_HIDDEN_KEY) === '1'
58
+ const completelyHidden = localStorage.getItem(CHROME_COMPLETELY_HIDDEN_KEY) === '1'
57
59
  if (hidden) {
58
60
  document.documentElement.classList.add('storyboard-chrome-hidden')
59
61
  }
62
+ if (completelyHidden) {
63
+ document.documentElement.classList.add('storyboard-chrome-completely-hidden')
64
+ }
60
65
  }
61
66
 
62
67
  /**
63
- * Watch for changes to the storyboard-chrome-hidden class and persist to
64
- * localStorage. Works regardless of which code path toggles the class.
68
+ * Watch for changes to chrome-hidden / chrome-completely-hidden classes
69
+ * and persist to localStorage. Works regardless of which code path toggles them.
65
70
  */
66
71
  function installChromeStatePersistence() {
67
72
  if (typeof document === 'undefined' || typeof localStorage === 'undefined') return
68
73
  const observer = new MutationObserver(() => {
69
74
  const hidden = document.documentElement.classList.contains('storyboard-chrome-hidden')
75
+ const completelyHidden = document.documentElement.classList.contains('storyboard-chrome-completely-hidden')
70
76
  localStorage.setItem(CHROME_HIDDEN_KEY, hidden ? '1' : '0')
77
+ localStorage.setItem(CHROME_COMPLETELY_HIDDEN_KEY, completelyHidden ? '1' : '0')
71
78
  })
72
79
  observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] })
73
80
  }
@@ -17,6 +17,7 @@ export async function handler() {
17
17
  execute: () => {
18
18
  const isHidden = document.documentElement.classList.contains('storyboard-chrome-hidden')
19
19
  document.documentElement.classList.toggle('storyboard-chrome-hidden', !isHidden)
20
+ document.documentElement.classList.remove('storyboard-chrome-completely-hidden')
20
21
  },
21
22
  }]
22
23
  },