@@ -91,6 +91,8 @@ declare global {
9191 }
9292}
9393
94+ type PanelOrientation = 'horizontal' | 'vertical' ;
95+
9496@customElement ( 'gl-graph-details-panel' )
9597export class GlGraphDetailsPanel extends SignalWatcher ( LitElement ) {
9698 @consume ( { context : graphServicesContext , subscribe : true } )
@@ -440,9 +442,22 @@ export class GlGraphDetailsPanel extends SignalWatcher(LitElement) {
440442 return this ;
441443 }
442444
445+ private _resizeObserver ?: ResizeObserver ;
446+ @state ( ) private _preferredCompareOrientation : PanelOrientation = 'vertical' ;
447+
443448 override connectedCallback ( ) : void {
444449 super . connectedCallback ?.( ) ;
445450 this . addEventListener ( 'switch-model' , this . handleSwitchModel ) ;
451+ this . _preferredCompareOrientation = this . clientWidth >= 600 ? 'horizontal' : 'vertical' ;
452+ this . _resizeObserver = new ResizeObserver ( entries => {
453+ const preferred : PanelOrientation =
454+ ( entries [ 0 ] ?. contentRect . width ?? this . clientWidth ) >= 600 ? 'horizontal' : 'vertical' ;
455+ if ( this . _preferredCompareOrientation !== preferred ) {
456+ this . _preferredCompareOrientation = preferred ;
457+ this . autoFlipCompareOrientation ( ) ;
458+ }
459+ } ) ;
460+ this . _resizeObserver . observe ( this ) ;
446461 }
447462
448463 private handleSwitchModel = ( ) : void => {
@@ -518,6 +533,8 @@ export class GlGraphDetailsPanel extends SignalWatcher(LitElement) {
518533 override disconnectedCallback ( ) : void {
519534 super . disconnectedCallback ?.( ) ;
520535 this . removeEventListener ( 'switch-model' , this . handleSwitchModel ) ;
536+ this . _resizeObserver ?. disconnect ( ) ;
537+ this . _resizeObserver = undefined ;
521538 clearTimeout ( this . _suppressContentOverflowTimer ) ;
522539 this . _suppressContentOverflowTimer = undefined ;
523540 clearTimeout ( this . _suppressModePanelOverflowTimer ) ;
@@ -1014,19 +1031,19 @@ export class GlGraphDetailsPanel extends SignalWatcher(LitElement) {
10141031
10151032 const compareSheet = compareSheetOpen
10161033 ? ( ( ) => {
1017- // Sheet → pinned panel: default click always moves to beside (horizontal),
1018- // Alt-click moves to below (vertical). Icon + tooltip preview the live action
1019- // based on the alt-key state so the affordance reads correctly mid-press.
1020- const labelFor = ( o : 'horizontal' | 'vertical' ) =>
1021- o === 'horizontal' ? 'Move Beside' : 'Move Below' ;
1022- const iconFor = ( o : 'horizontal' | 'vertical' ) =>
1034+ // Click pins to preferred orientation; Alt-click flips it.
1035+ // Icon + tooltip update live with the Alt-key so the affordance previews the actual action.
1036+ const labelFor = ( o : PanelOrientation ) => ( o === 'horizontal' ? 'Move Beside' : 'Move Below' ) ;
1037+ const iconFor = ( o : PanelOrientation ) =>
10231038 o === 'horizontal' ? 'layout-sidebar-right' : 'layout-panel' ;
1024- const effective : 'horizontal' | 'vertical' = this . _modifiers . altKey ? 'vertical' : 'horizontal' ;
1039+ const preferred = this . _preferredCompareOrientation ;
1040+ const alternate = this . flipOrientation ( preferred ) ;
1041+ const effective = this . _modifiers . altKey ? alternate : preferred ;
10251042 const actionLabel = labelFor ( effective ) ;
10261043 const actionIcon = iconFor ( effective ) ;
10271044 const tooltipContent = this . _modifiers . altKey
10281045 ? actionLabel
1029- : `${ actionLabel } \n[${ getAltKeySymbol ( ) } ] ${ labelFor ( 'vertical' ) } ` ;
1046+ : `${ actionLabel } \n[${ getAltKeySymbol ( ) } ] ${ labelFor ( alternate ) } ` ;
10301047 return html `< gl-detail-sheet
10311048 aria-label ="Compare "
10321049 sheet-title ="Comparing References "
@@ -1091,23 +1108,33 @@ export class GlGraphDetailsPanel extends SignalWatcher(LitElement) {
10911108 } ;
10921109
10931110 private handleOpenCompareAsPanel = ( e : MouseEvent ) : void => {
1094- // Sheet → pinned panel: default click always moves to beside (horizontal); Alt-click
1095- // moves to below (vertical). The orientation preview in the sheet header tooltip mirrors
1096- // this so the affordance reads correctly mid-press.
1097- // Tell the sheet to skip its focus-restoration step on disconnect — the user is
1098- // transitioning INTO the new pinned panel, not dismissing the sheet, so returning focus
1099- // to whatever row was focused before the sheet opened is the wrong direction.
1111+ // Skip the sheet's focus-restoration — the user is transitioning INTO the panel,
1112+ // not dismissing the sheet.
11001113 const sheet = this . querySelector ( 'gl-detail-sheet' ) ;
11011114 if ( sheet != null ) {
11021115 ( sheet as { skipFocusRestore : boolean } ) . skipFocusRestore = true ;
11031116 }
1104- const target : 'horizontal' | 'vertical' = e . altKey ? 'vertical' : 'horizontal' ;
1117+
1118+ const preferred = this . _preferredCompareOrientation ;
1119+ const target = e . altKey ? this . flipOrientation ( preferred ) : preferred ;
11051120 this . _workflow . openCompareAsPanel ( target ) ;
11061121 } ;
11071122
1123+ private flipOrientation ( o : PanelOrientation ) : PanelOrientation {
1124+ return o === 'horizontal' ? 'vertical' : 'horizontal' ;
1125+ }
1126+
1127+ private autoFlipCompareOrientation ( ) : void {
1128+ if ( ! this . _state . compareAsPanel . get ( ) ) return ;
1129+
1130+ const preferred = this . _preferredCompareOrientation ;
1131+ if ( this . _state . compareSplitOrientation . get ( ) !== preferred ) {
1132+ this . _state . compareSplitOrientation . set ( preferred ) ;
1133+ }
1134+ }
1135+
11081136 private handleFlipCompareOrientation = ( ) : void => {
1109- const current = this . _state . compareSplitOrientation . get ( ) ;
1110- this . _state . compareSplitOrientation . set ( current === 'horizontal' ? 'vertical' : 'horizontal' ) ;
1137+ this . _state . compareSplitOrientation . set ( this . flipOrientation ( this . _state . compareSplitOrientation . get ( ) ) ) ;
11111138 } ;
11121139
11131140 private handleCompareSplitChange = ( e : CustomEvent < { position : number } > ) : void => {
0 commit comments