@@ -186,9 +186,37 @@ export function buildExtrasPane(parent, bootstrapState, formRegistry, context) {
186186 createField ( optionsGrid , "Face Restoration" , elements . faceRestoration ) ;
187187 createField ( optionsGrid , "CodeFormer Weight" , elements . codeformerWeight ) ;
188188
189- const actionRail = document . createElement ( "div" ) ;
190- actionRail . className = "rookieui-shell__action-rail rookieui-shell__action-rail--extras" ;
191- rightColumn . appendChild ( actionRail ) ;
189+ const actionRail = document . createElement ( "div" ) ;
190+ actionRail . className = "rookieui-shell__action-rail rookieui-shell__action-rail--extras" ;
191+ rightColumn . appendChild ( actionRail ) ;
192+
193+ let extrasRailAlignRafToken = null ;
194+ const resolveActiveExtrasPane = ( ) => ( state . mode === "batch_process" ? batchPane : singlePane ) ;
195+ const syncExtrasActionRailAlignment = ( ) => {
196+ const ownerPane = section . closest ( ".rookieui-shell__pane" ) ;
197+ if ( ownerPane ?. hidden ) {
198+ return ;
199+ }
200+ const activePaneRect = resolveActiveExtrasPane ( ) . getBoundingClientRect ( ) ;
201+ const actionRailRect = actionRail . getBoundingClientRect ( ) ;
202+ const currentMarginTop = Number . parseFloat ( globalThis . getComputedStyle ?. ( actionRail ) ?. marginTop ?? "0" ) || 0 ;
203+ const marginTop = Math . max ( 0 , Math . round ( currentMarginTop + ( activePaneRect . top - actionRailRect . top ) ) ) ;
204+ // CRITICAL: keep Extras rail alignment dynamic; fixed offsets drift across Linux/Windows font metrics and cause flaky E2E top-delta checks.
205+ actionRail . style . marginTop = `${ marginTop } px` ;
206+ } ;
207+ const queueExtrasActionRailAlignment = ( ) => {
208+ if ( extrasRailAlignRafToken !== null && typeof globalThis . cancelAnimationFrame === "function" ) {
209+ globalThis . cancelAnimationFrame ( extrasRailAlignRafToken ) ;
210+ }
211+ if ( typeof globalThis . requestAnimationFrame === "function" ) {
212+ extrasRailAlignRafToken = globalThis . requestAnimationFrame ( ( ) => {
213+ extrasRailAlignRafToken = null ;
214+ syncExtrasActionRailAlignment ( ) ;
215+ } ) ;
216+ return ;
217+ }
218+ syncExtrasActionRailAlignment ( ) ;
219+ } ;
192220
193221 const submitButton = document . createElement ( "button" ) ;
194222 submitButton . id = "rookieui-extras-submit" ;
@@ -349,15 +377,31 @@ export function buildExtrasPane(parent, bootstrapState, formRegistry, context) {
349377 }
350378 } ) ;
351379
352- singleButton . addEventListener ( "click" , ( ) => {
353- state . mode = "single_image" ;
354- syncExtrasMode ( [ singleButton , batchButton ] , [ singlePane , batchPane ] , state . mode ) ;
355- } ) ;
356- batchButton . addEventListener ( "click" , ( ) => {
357- state . mode = "batch_process" ;
358- syncExtrasMode ( [ singleButton , batchButton ] , [ singlePane , batchPane ] , state . mode ) ;
359- } ) ;
360- syncExtrasMode ( [ singleButton , batchButton ] , [ singlePane , batchPane ] , state . mode ) ;
380+ singleButton . addEventListener ( "click" , ( ) => {
381+ state . mode = "single_image" ;
382+ syncExtrasMode ( [ singleButton , batchButton ] , [ singlePane , batchPane ] , state . mode ) ;
383+ syncExtrasActionRailAlignment ( ) ;
384+ queueExtrasActionRailAlignment ( ) ;
385+ } ) ;
386+ batchButton . addEventListener ( "click" , ( ) => {
387+ state . mode = "batch_process" ;
388+ syncExtrasMode ( [ singleButton , batchButton ] , [ singlePane , batchPane ] , state . mode ) ;
389+ syncExtrasActionRailAlignment ( ) ;
390+ queueExtrasActionRailAlignment ( ) ;
391+ } ) ;
392+ syncExtrasMode ( [ singleButton , batchButton ] , [ singlePane , batchPane ] , state . mode ) ;
393+ queueExtrasActionRailAlignment ( ) ;
394+
395+ if ( typeof ResizeObserver === "function" ) {
396+ const extrasAlignObserver = new ResizeObserver ( ( ) => {
397+ queueExtrasActionRailAlignment ( ) ;
398+ } ) ;
399+ extrasAlignObserver . observe ( modeTabs ) ;
400+ extrasAlignObserver . observe ( singlePane ) ;
401+ extrasAlignObserver . observe ( batchPane ) ;
402+ section . __extrasAlignObserver = extrasAlignObserver ;
403+ }
404+ globalThis . addEventListener ?. ( "resize" , queueExtrasActionRailAlignment ) ;
361405
362406 let extrasModeSnapshot = state . mode ;
363407 const extrasStateLock = installPaneStateLock ( formRegistry , "extras" , elements , ( ) => {
@@ -379,8 +423,12 @@ export function buildExtrasPane(parent, bootstrapState, formRegistry, context) {
379423 captureExtrasState ( ) ;
380424 } ) ;
381425
382- return {
383- onActivate : restoreExtrasState ,
384- onDeactivate : captureExtrasState ,
385- } ;
426+ return {
427+ onActivate : ( ) => {
428+ restoreExtrasState ( ) ;
429+ syncExtrasActionRailAlignment ( ) ;
430+ queueExtrasActionRailAlignment ( ) ;
431+ } ,
432+ onDeactivate : captureExtrasState ,
433+ } ;
386434}
0 commit comments