@@ -305,6 +305,161 @@ describe("DynamicPage", () => {
305305
306306 cy . get ( "[data-testid='bottom-input']" ) . should ( "be.visible" ) ;
307307 } ) ;
308+
309+ it ( "does not scroll content when a button is clicked while the header is partially hidden" , ( ) => {
310+ let clickCount = 0 ;
311+
312+ cy . mount (
313+ < DynamicPage style = { { height : "400px" } } >
314+ < DynamicPageTitle slot = "titleArea" >
315+ < div slot = "heading" > Page Title</ div >
316+ </ DynamicPageTitle >
317+ < DynamicPageHeader slot = "headerArea" >
318+ < div style = { { height : "180px" } } >
319+ < div > Line 1</ div >
320+ < div > Line 2</ div >
321+ < div > Line 3</ div >
322+ < div > Line 4</ div >
323+ < div > Rack: 34</ div >
324+ </ div >
325+ </ DynamicPageHeader >
326+ < Button data-testid = "content-button" onClick = { ( ) => { clickCount += 1 ; } } > test</ Button >
327+ < div style = { { height : "1000px" } } > </ div >
328+ </ DynamicPage >
329+ ) ;
330+
331+ cy . get ( "[ui5-dynamic-page]" )
332+ . shadow ( )
333+ . find ( ".ui5-dynamic-page-scroll-container" )
334+ . then ( ( $container ) => {
335+ $container [ 0 ] . scrollTop = 120 ;
336+ } ) ;
337+
338+ cy . get ( "[ui5-dynamic-page]" )
339+ . shadow ( )
340+ . find ( ".ui5-dynamic-page-scroll-container" )
341+ . then ( ( $container ) => {
342+ const initialScrollTop = $container [ 0 ] . scrollTop ;
343+
344+ cy . get ( "[data-testid='content-button']" )
345+ . realClick ( ) ;
346+
347+ cy . then ( ( ) => {
348+ expect ( clickCount ) . to . equal ( 1 ) ;
349+ } ) ;
350+
351+ cy . get ( "[ui5-dynamic-page]" )
352+ . shadow ( )
353+ . find ( ".ui5-dynamic-page-scroll-container" )
354+ . should ( ( $updatedContainer ) => {
355+ expect ( $updatedContainer [ 0 ] . scrollTop ) . to . be . closeTo ( initialScrollTop , 1 ) ;
356+ } ) ;
357+ } ) ;
358+ } ) ;
359+
360+ it ( "does not scroll content when a visible button receives keyboard focus while the header is partially hidden" , ( ) => {
361+ cy . mount (
362+ < DynamicPage style = { { height : "400px" } } >
363+ < DynamicPageTitle slot = "titleArea" >
364+ < div slot = "heading" > Page Title</ div >
365+ </ DynamicPageTitle >
366+ < DynamicPageHeader slot = "headerArea" >
367+ < div style = { { height : "180px" } } >
368+ < div > Line 1</ div >
369+ < div > Line 2</ div >
370+ < div > Line 3</ div >
371+ < div > Line 4</ div >
372+ < div > Rack: 34</ div >
373+ </ div >
374+ </ DynamicPageHeader >
375+ < button data-testid = "first-content-button" > first</ button >
376+ < Button data-testid = "content-button" > test</ Button >
377+ < div style = { { height : "1000px" } } > </ div >
378+ </ DynamicPage >
379+ ) ;
380+
381+ cy . get ( "[ui5-dynamic-page]" )
382+ . shadow ( )
383+ . find ( ".ui5-dynamic-page-scroll-container" )
384+ . then ( ( $container ) => {
385+ $container [ 0 ] . scrollTop = 120 ;
386+ } ) ;
387+
388+ cy . get ( "[data-testid='first-content-button']" )
389+ . focus ( )
390+ . should ( "be.focused" ) ;
391+
392+ cy . get ( "[ui5-dynamic-page]" )
393+ . shadow ( )
394+ . find ( ".ui5-dynamic-page-scroll-container" )
395+ . then ( ( $container ) => {
396+ const initialScrollTop = $container [ 0 ] . scrollTop ;
397+
398+ cy . realPress ( "Tab" ) ;
399+
400+ cy . get ( "[data-testid='content-button']" )
401+ . should ( "be.focused" ) ;
402+
403+ cy . get ( "[ui5-dynamic-page]" )
404+ . shadow ( )
405+ . find ( ".ui5-dynamic-page-scroll-container" )
406+ . should ( ( $updatedContainer ) => {
407+ expect ( $updatedContainer [ 0 ] . scrollTop ) . to . be . closeTo ( initialScrollTop , 1 ) ;
408+ } ) ;
409+ } ) ;
410+ } ) ;
411+
412+ it ( "scrolls a partially clipped textarea into view when focused via Tab" , ( ) => {
413+ cy . mount (
414+ < DynamicPage style = { { height : "400px" } } >
415+ < DynamicPageTitle slot = "titleArea" >
416+ < div slot = "heading" > Page Title</ div >
417+ </ DynamicPageTitle >
418+ < DynamicPageHeader slot = "headerArea" >
419+ < div style = { { height : "180px" } } >
420+ < div > Line 1</ div >
421+ < div > Line 2</ div >
422+ < div > Line 3</ div >
423+ < div > Line 4</ div >
424+ < div > Rack: 34</ div >
425+ </ div >
426+ </ DynamicPageHeader >
427+ < button data-testid = "before-textarea" > Before</ button >
428+ < textarea data-testid = "target-textarea" style = { { display : "block" , marginTop : "8px" , height : "120px" } } />
429+ < div style = { { height : "1000px" } } > </ div >
430+ </ DynamicPage >
431+ ) ;
432+
433+ cy . get ( "[ui5-dynamic-page]" )
434+ . shadow ( )
435+ . find ( ".ui5-dynamic-page-scroll-container" )
436+ . then ( ( $container ) => {
437+ $container [ 0 ] . scrollTop = 120 ;
438+ } ) ;
439+
440+ cy . get ( "[data-testid='before-textarea']" )
441+ . focus ( )
442+ . should ( "be.focused" ) ;
443+
444+ cy . realPress ( "Tab" ) ;
445+
446+ cy . get ( "[data-testid='target-textarea']" )
447+ . should ( "be.focused" ) ;
448+
449+ cy . get ( "[ui5-dynamic-page]" )
450+ . then ( ( $dp ) => {
451+ const dp = $dp [ 0 ] as DynamicPage ;
452+ const containerRect = dp . scrollContainer ! . getBoundingClientRect ( ) ;
453+ const contentEl = dp . shadowRoot ! . querySelector < HTMLElement > ( ".ui5-dynamic-page-content" ) ! ;
454+ const contentRect = contentEl . getBoundingClientRect ( ) ;
455+ const targetRect = ( dp . querySelector ( "[data-testid='target-textarea']" ) as HTMLTextAreaElement ) . getBoundingClientRect ( ) ;
456+ const visibleTop = Math . max ( containerRect . top , contentRect . top ) ;
457+ const visibleBottom = containerRect . bottom - dp . endAreaHeight ;
458+
459+ expect ( targetRect . top ) . to . be . at . least ( visibleTop ) ;
460+ expect ( targetRect . bottom ) . to . be . at . most ( visibleBottom ) ;
461+ } ) ;
462+ } ) ;
308463} ) ;
309464
310465describe ( "Scroll" , ( ) => {
0 commit comments