@@ -188,7 +188,6 @@ class DynamicPage extends UI5Element {
188188 skipSnapOnScroll = false ;
189189 showHeaderInStickArea = false ;
190190 isToggled = false ;
191- _focusInHandler ?: ( e : FocusEvent ) => void ;
192191
193192 @property ( { type : Boolean } )
194193 _headerSnapped = false ;
@@ -213,52 +212,16 @@ class DynamicPage extends UI5Element {
213212 if ( this . dynamicPageHeader ) {
214213 this . dynamicPageHeader . _snapped = this . _headerSnapped ;
215214 }
216- const titleHeight = this . dynamicPageTitle ?. getBoundingClientRect ( ) . height || 0 ;
217- const headerHeight = this . dynamicPageHeader ?. getBoundingClientRect ( ) . height || 0 ;
218- const footerHeight = this . showFooter ? this . footerWrapper ?. getBoundingClientRect ( ) . height : 0 ;
219-
220- if ( this . scrollContainer ) {
221- this . scrollContainer . style . setProperty ( "scroll-padding-block-end" , `${ footerHeight } px` ) ;
222-
223- if ( this . _headerSnapped ) {
224- this . scrollContainer . style . setProperty ( "scroll-padding-block-start" , `${ titleHeight } px` ) ;
225- } else {
226- this . scrollContainer . style . setProperty ( "scroll-padding-block-start" , `${ headerHeight + titleHeight } px` ) ;
227- }
228- }
229215 }
230216
231- onAfterRendering ( ) {
232- if ( this . scrollContainer ) {
233- if ( this . _focusInHandler ) {
234- this . scrollContainer . removeEventListener ( "focusin" , this . _focusInHandler ) ;
235- }
236-
237- this . _focusInHandler = ( e : FocusEvent ) => {
238- const target = e . target as HTMLElement ;
239-
240- if ( ! target || target === this . scrollContainer ) {
241- return ;
242- }
243-
244- if ( this . dynamicPageHeader ?. contains ( target ) || this . dynamicPageTitle ?. contains ( target ) ) {
245- return ;
246- }
247-
248- requestAnimationFrame ( ( ) => {
249- target . scrollIntoView ( { behavior : "smooth" , block : "nearest" } ) ;
250- } ) ;
251- } ;
252-
253- this . scrollContainer . addEventListener ( "focusin" , this . _focusInHandler ) ;
254- }
217+ get endAreaHeight ( ) {
218+ return this . showFooter ? this . footerWrapper ?. getBoundingClientRect ( ) . height || 0 : 0 ;
255219 }
256220
257- onExitDOM ( ) {
258- if ( this . scrollContainer && this . _focusInHandler ) {
259- this . scrollContainer . removeEventListener ( "focusin" , this . _focusInHandler ) ;
260- this . _focusInHandler = undefined ;
261- }
221+ get topAreaHeight ( ) {
222+ const titleHeight = this . dynamicPageTitle ?. getBoundingClientRect ( ) . height || 0 ;
223+ const headerHeight = this . dynamicPageHeader ?. getBoundingClientRect ( ) . height || 0 ;
224+ return this . _headerSnapped ? titleHeight : headerHeight + titleHeight ;
262225 }
263226
264227 get dynamicPageTitle ( ) : DynamicPageTitle | null {
@@ -464,14 +427,35 @@ class DynamicPage extends UI5Element {
464427 }
465428 }
466429
467- async onExpandHoverIn ( ) {
430+ onExpandHoverIn ( ) {
468431 this . dynamicPageTitle ?. setAttribute ( "hovered" , "" ) ;
469- await renderFinished ( ) ;
470432 }
471433
472- async onExpandHoverOut ( ) {
434+ onExpandHoverOut ( ) {
473435 this . dynamicPageTitle ?. removeAttribute ( "hovered" ) ;
474- await renderFinished ( ) ;
436+ }
437+
438+ onContentFocusIn ( e : FocusEvent ) {
439+ const target = e . target as HTMLElement ;
440+ this . setScrollPadding ( { start : this . topAreaHeight , end : this . endAreaHeight } ) ;
441+ // textareas and similar elements appear "in view" even when partially
442+ // hidden behind sticky header/footer.
443+ // manual scroll brings them fully into view.
444+ // another issue is that browsers do not reflect dynamic changes of scroll-padding
445+ requestAnimationFrame ( ( ) => {
446+ target . scrollIntoView ( { behavior : "smooth" , block : "nearest" } ) ;
447+ } ) ;
448+ }
449+
450+ onContentFocusOut ( ) {
451+ // Reset scroll padding when focus leaves content (e.g., moves to sticky header).
452+ // The sticky header is part of the scrollable area, so keeping padding causes unwanted scroll.
453+ this . setScrollPadding ( { start : 0 , end : 0 } ) ;
454+ }
455+
456+ setScrollPadding ( padding : { start : number , end : number } ) {
457+ this . scrollContainer ?. style . setProperty ( "scroll-padding-top" , `${ padding . start } px` ) ;
458+ this . scrollContainer ?. style . setProperty ( "scroll-padding-bottom" , `${ padding . end } px` ) ;
475459 }
476460}
477461
0 commit comments