@@ -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,46 @@ 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+ < span className = { `custom-embed__lock-icon__text ${ isHandToolActive ? 'visible' : '' } ` } >
152+ (Hand tool)
153+ </ span >
121154 </ div >
122155 ) ;
123156} ;
124157
125- // Track scrolling state
126- let isScrolling = false ;
158+ // Track scrolling state globally
159+ let globalIsScrolling = false ;
127160// Create a custom event for scrolling state changes
128161const scrollStateChangeEvent = new CustomEvent ( 'scrollStateChange' , { detail : { isScrolling : false } } ) ;
129162
@@ -137,7 +170,7 @@ const getDebouncedScrollEnd = (() => {
137170 if ( currentDebounceTime !== lastDebounceTime || ! debouncedFn ) {
138171 lastDebounceTime = currentDebounceTime ;
139172 debouncedFn = debounce ( ( ) => {
140- isScrolling = false ;
173+ globalIsScrolling = false ;
141174 // Set pointer-events back to all when not scrolling
142175 document . documentElement . style . setProperty ( '--embeddable-pointer-events' , 'all' ) ;
143176 // Dispatch event with updated scrolling state
@@ -153,16 +186,23 @@ export const lockEmbeddables = (appState?: AppState) => {
153186 // Get the debounce time from settings, with fallback to default
154187 const debounceTime = appState ?. pad ?. userSettings ?. embedLockDebounceTime || 350 ;
155188
156- if ( ! isScrolling ) {
157- isScrolling = true ;
158- // Set pointer-events to none during scrolling
189+ // Check if hand tool is active
190+ const handToolActive = appState ?. activeTool ?. type === "hand" ;
191+
192+ if ( ! globalIsScrolling ) {
193+ globalIsScrolling = true ;
194+ // Set pointer-events to none during scrolling or when hand tool is active
159195 document . documentElement . style . setProperty ( '--embeddable-pointer-events' , 'none' ) ;
160196 // Dispatch event with updated scrolling state
161197 scrollStateChangeEvent . detail . isScrolling = true ;
162198 document . dispatchEvent ( scrollStateChangeEvent ) ;
163199 }
164200
165- // Get the current debounced function and call it
166- const debouncedScrollEnd = getDebouncedScrollEnd ( debounceTime ) ;
167- debouncedScrollEnd ( ) ;
201+ // If hand tool is not active, use debounce to unlock after scrolling stops
202+ // If hand tool is active, we don't want to unlock
203+ if ( ! handToolActive ) {
204+ // Get the current debounced function and call it
205+ const debouncedScrollEnd = getDebouncedScrollEnd ( debounceTime ) ;
206+ debouncedScrollEnd ( ) ;
207+ }
168208} ;
0 commit comments