@@ -73,7 +73,7 @@ export const renderCustomEmbeddable = (
7373 < div className = "custom-embed" >
7474 < div className = "custom-embed__title-bar" >
7575 < div className = "custom-embed__title-bar__text" > { title } </ div >
76- < LockIndicator />
76+ < LockIndicator appState = { appState } />
7777 </ div >
7878 < div className = "custom-embed__content" >
7979 { content }
@@ -87,7 +87,7 @@ export const renderCustomEmbeddable = (
8787 < div className = "custom-embed" >
8888 < div className = "custom-embed__title-bar" >
8989 < div className = "custom-embed__title-bar__text" > { title } </ div >
90- < LockIndicator />
90+ < LockIndicator appState = { appState } />
9191 </ div >
9292 < div className = "custom-embed__content" >
9393 < iframe className = "custom-embed__content--iframe" src = { element . link } />
@@ -97,13 +97,15 @@ export const renderCustomEmbeddable = (
9797 }
9898} ;
9999
100- // Lock icon component that shows when scrolling
101- const LockIndicator = ( ) => {
102- const [ visible , setVisible ] = useState ( false ) ;
100+ // Lock icon component that shows when scrolling or when hand tool is active
101+ const LockIndicator = ( { appState } : { appState ?: AppState } ) => {
102+ const [ isScrolling , setIsScrolling ] = useState ( false ) ;
103+ const [ isHandToolActive , setIsHandToolActive ] = useState ( false ) ;
103104
105+ // Effect to handle scroll state changes
104106 useEffect ( ( ) => {
105107 const handleScrollStateChange = ( event : CustomEvent < { isScrolling : boolean } > ) => {
106- setVisible ( event . detail . isScrolling ) ;
108+ setIsScrolling ( event . detail . isScrolling ) ;
107109 } ;
108110
109111 // Add event listener for scroll state changes
@@ -115,15 +117,48 @@ const LockIndicator = () => {
115117 } ;
116118 } , [ ] ) ;
117119
120+ // Separate effect to handle hand tool state changes
121+ useEffect ( ( ) => {
122+ // Check hand tool state
123+ const handToolActive = appState ?. activeTool ?. type === "hand" ;
124+ const wasHandToolActive = isHandToolActive ;
125+ setIsHandToolActive ( handToolActive ) ;
126+
127+ // If hand tool was active but is now deactivated
128+ if ( wasHandToolActive && ! handToolActive ) {
129+ // Force reset of global scrolling state
130+ globalIsScrolling = false ;
131+ document . documentElement . style . setProperty ( '--embeddable-pointer-events' , 'all' ) ;
132+
133+ // Dispatch event to update all components
134+ scrollStateChangeEvent . detail . isScrolling = false ;
135+ document . dispatchEvent ( scrollStateChangeEvent ) ;
136+
137+ // Update component state
138+ setIsScrolling ( false ) ;
139+ } else if ( handToolActive ) {
140+ // Set pointer-events to none when hand tool is active
141+ document . documentElement . style . setProperty ( '--embeddable-pointer-events' , 'none' ) ;
142+ }
143+ } , [ appState ] ) ;
144+
145+ // Determine if the lock should be visible
146+ const visible = isScrolling || isHandToolActive ;
147+
118148 return (
119149 < div className = { `custom-embed__lock-icon ${ visible ? 'visible' : '' } ` } >
120150 < Lock size = { 16 } />
151+ { isHandToolActive && (
152+ < span className = "custom-embed__lock-icon__text visible" >
153+ (Hand tool)
154+ </ span >
155+ ) }
121156 </ div >
122157 ) ;
123158} ;
124159
125- // Track scrolling state
126- let isScrolling = false ;
160+ // Track scrolling state globally
161+ let globalIsScrolling = false ;
127162// Create a custom event for scrolling state changes
128163const scrollStateChangeEvent = new CustomEvent ( 'scrollStateChange' , { detail : { isScrolling : false } } ) ;
129164
@@ -137,7 +172,7 @@ const getDebouncedScrollEnd = (() => {
137172 if ( currentDebounceTime !== lastDebounceTime || ! debouncedFn ) {
138173 lastDebounceTime = currentDebounceTime ;
139174 debouncedFn = debounce ( ( ) => {
140- isScrolling = false ;
175+ globalIsScrolling = false ;
141176 // Set pointer-events back to all when not scrolling
142177 document . documentElement . style . setProperty ( '--embeddable-pointer-events' , 'all' ) ;
143178 // Dispatch event with updated scrolling state
@@ -153,16 +188,23 @@ export const lockEmbeddables = (appState?: AppState) => {
153188 // Get the debounce time from settings, with fallback to default
154189 const debounceTime = appState ?. pad ?. userSettings ?. embedLockDebounceTime || 350 ;
155190
156- if ( ! isScrolling ) {
157- isScrolling = true ;
158- // Set pointer-events to none during scrolling
191+ // Check if hand tool is active
192+ const handToolActive = appState ?. activeTool ?. type === "hand" ;
193+
194+ if ( ! globalIsScrolling ) {
195+ globalIsScrolling = true ;
196+ // Set pointer-events to none during scrolling or when hand tool is active
159197 document . documentElement . style . setProperty ( '--embeddable-pointer-events' , 'none' ) ;
160198 // Dispatch event with updated scrolling state
161199 scrollStateChangeEvent . detail . isScrolling = true ;
162200 document . dispatchEvent ( scrollStateChangeEvent ) ;
163201 }
164202
165- // Get the current debounced function and call it
166- const debouncedScrollEnd = getDebouncedScrollEnd ( debounceTime ) ;
167- debouncedScrollEnd ( ) ;
203+ // If hand tool is not active, use debounce to unlock after scrolling stops
204+ // If hand tool is active, we don't want to unlock
205+ if ( ! handToolActive ) {
206+ // Get the current debounced function and call it
207+ const debouncedScrollEnd = getDebouncedScrollEnd ( debounceTime ) ;
208+ debouncedScrollEnd ( ) ;
209+ }
168210} ;
0 commit comments