@@ -114,14 +114,39 @@ export function createStagePublisher(deps: StagePublisherDeps): StagePublisher {
114114 let lastMovement = performance . now ( ) ;
115115 let appliedT = - 1 ;
116116 const iframe = deps . section . querySelector < HTMLIFrameElement > ( '.stage-frame-iframe' ) ;
117+ const exploreButton = deps . section . querySelector < HTMLButtonElement > ( '[data-stage-explore]' ) ;
118+ let exploring = false ;
119+ const setExploring = ( value : boolean ) => {
120+ if ( exploring === value ) return ;
121+ exploring = value ;
122+ deps . section . toggleAttribute ( 'data-exploring' , value ) ;
123+ if ( exploreButton ) {
124+ exploreButton . textContent = value ? 'Resume walkthrough' : 'Explore chat' ;
125+ exploreButton . setAttribute ( 'aria-pressed' , String ( value ) ) ;
126+ }
127+ deps . frameWindow ( ) ?. postMessage ( { type : STAGE_MESSAGE_TYPE , explore : value } , STAGE_DEMO_ORIGIN ) ;
128+ } ;
129+ const toggleExploring = ( ) => {
130+ if ( deps . section . hasAttribute ( 'data-interactive' ) ) setExploring ( ! exploring ) ;
131+ } ;
132+ const onKey = ( event : KeyboardEvent ) => {
133+ if ( event . key === 'Escape' && exploring ) {
134+ setExploring ( false ) ;
135+ exploreButton ?. focus ( { preventScroll : true } ) ;
136+ }
137+ } ;
138+ exploreButton ?. addEventListener ( 'click' , toggleExploring ) ;
139+ window . addEventListener ( 'keydown' , onKey ) ;
117140 const setInteractive = ( enabled : boolean ) => {
118141 deps . section . toggleAttribute ( 'data-interactive' , enabled ) ;
142+ if ( exploreButton ) exploreButton . disabled = ! enabled ;
119143 if ( iframe ) {
120144 iframe . toggleAttribute ( 'inert' , ! enabled ) ;
121145 iframe . tabIndex = enabled ? 0 : - 1 ;
122146 }
123147 } ;
124148 const onScroll = ( ) => {
149+ setExploring ( false ) ;
125150 lastMovement = performance . now ( ) ;
126151 setInteractive ( false ) ;
127152 } ;
@@ -148,6 +173,22 @@ export function createStagePublisher(deps: StagePublisherDeps): StagePublisher {
148173 return ;
149174 const d = e . data as Record < string , unknown > | null ;
150175 if ( ! d || typeof d !== 'object' || d [ 'type' ] !== STAGE_MESSAGE_TYPE ) return ;
176+ if ( d [ 'explore' ] === false ) {
177+ setExploring ( false ) ;
178+ exploreButton ?. focus ( { preventScroll : true } ) ;
179+ return ;
180+ }
181+ const wheel = d [ 'wheel' ] as { deltaX ?: unknown ; deltaY ?: unknown } | undefined ;
182+ if ( ready && ! exploring && wheel && isFiniteNumber ( wheel . deltaX ) && isFiniteNumber ( wheel . deltaY ) ) {
183+ onScroll ( ) ;
184+ const limit = window . innerHeight * 2 ;
185+ window . scrollBy ( {
186+ left : Math . max ( - limit , Math . min ( limit , wheel . deltaX ) ) ,
187+ top : Math . max ( - limit , Math . min ( limit , wheel . deltaY ) ) ,
188+ behavior : 'instant' ,
189+ } ) ;
190+ return ;
191+ }
151192 if ( d [ 'ready' ] === true ) {
152193 if ( ! isReady ( d ) ) return ;
153194 const first = ready === null ;
@@ -249,6 +290,9 @@ export function createStagePublisher(deps: StagePublisherDeps): StagePublisher {
249290 } ,
250291 dispose ( ) {
251292 disposed = true ;
293+ setExploring ( false ) ;
294+ exploreButton ?. removeEventListener ( 'click' , toggleExploring ) ;
295+ window . removeEventListener ( 'keydown' , onKey ) ;
252296 window . removeEventListener ( 'message' , onMessage ) ;
253297 window . removeEventListener ( 'scroll' , onScroll ) ;
254298 setInteractive ( false ) ;
0 commit comments