@@ -36,6 +36,9 @@ const aiChatStatus = document.getElementById('ai-chat-status')
3636const aiChatRate = document . getElementById ( 'ai-chat-rate' )
3737const aiChatRepository = document . getElementById ( 'ai-chat-repository' )
3838const aiChatMessages = document . getElementById ( 'ai-chat-messages' )
39+ const viewControlsToggle = document . getElementById ( 'view-controls-toggle' )
40+ const viewControlsDrawer = document . getElementById ( 'view-controls-drawer' )
41+ const aiControlsToggle = document . getElementById ( 'ai-controls-toggle' )
3942const appGridLayoutButtons = document . querySelectorAll ( '[data-app-grid-layout]' )
4043const appThemeButtons = document . querySelectorAll ( '[data-app-theme]' )
4144const editorToolsButtons = document . querySelectorAll ( '[data-editor-tools-toggle]' )
@@ -84,6 +87,7 @@ let pendingClearAction = null
8487let suppressEditorChangeSideEffects = false
8588let hasAppliedReactModeDefault = false
8689const clipboardSupported = Boolean ( navigator . clipboard ?. writeText )
90+ const aiAssistantFeatureEnabled = isAiAssistantFeatureEnabled ( )
8791
8892const previewBackground = createPreviewBackgroundController ( {
8993 previewBgColorInput,
@@ -102,6 +106,66 @@ const { applyAppGridLayout, applyTheme, getInitialAppGridLayout, getInitialTheme
102106 layoutTheme
103107
104108const compactViewportMediaQuery = window . matchMedia ( '(max-width: 900px)' )
109+ const stackedRailMediaQuery = window . matchMedia ( '(max-width: 1090px)' )
110+ let stackedRailViewControlsOpen = false
111+ let compactAiControlsOpen = false
112+
113+ const isStackedRailViewport = ( ) => stackedRailMediaQuery . matches
114+
115+ const setStackedRailViewControlsOpen = isOpen => {
116+ if ( ! ( viewControlsToggle instanceof HTMLButtonElement ) || ! viewControlsDrawer ) {
117+ return
118+ }
119+
120+ if ( ! isStackedRailViewport ( ) ) {
121+ stackedRailViewControlsOpen = false
122+ viewControlsToggle . setAttribute ( 'aria-expanded' , 'false' )
123+ viewControlsDrawer . removeAttribute ( 'hidden' )
124+ return
125+ }
126+
127+ stackedRailViewControlsOpen = Boolean ( isOpen )
128+ viewControlsToggle . setAttribute (
129+ 'aria-expanded' ,
130+ stackedRailViewControlsOpen ? 'true' : 'false' ,
131+ )
132+
133+ if ( stackedRailViewControlsOpen ) {
134+ viewControlsDrawer . removeAttribute ( 'hidden' )
135+ return
136+ }
137+
138+ viewControlsDrawer . setAttribute ( 'hidden' , '' )
139+ }
140+
141+ const setCompactAiControlsOpen = isOpen => {
142+ if ( ! ( aiControlsToggle instanceof HTMLButtonElement ) || ! githubAiControls ) {
143+ return
144+ }
145+
146+ if ( ! aiAssistantFeatureEnabled ) {
147+ compactAiControlsOpen = false
148+ aiControlsToggle . setAttribute ( 'hidden' , '' )
149+ aiControlsToggle . setAttribute ( 'aria-expanded' , 'false' )
150+ githubAiControls . removeAttribute ( 'data-compact-open' )
151+ githubAiControls . setAttribute ( 'hidden' , '' )
152+ return
153+ }
154+
155+ aiControlsToggle . removeAttribute ( 'hidden' )
156+
157+ if ( ! isCompactViewport ( ) ) {
158+ compactAiControlsOpen = false
159+ aiControlsToggle . setAttribute ( 'aria-expanded' , 'false' )
160+ githubAiControls . removeAttribute ( 'data-compact-open' )
161+ githubAiControls . removeAttribute ( 'hidden' )
162+ return
163+ }
164+
165+ compactAiControlsOpen = Boolean ( isOpen )
166+ aiControlsToggle . setAttribute ( 'aria-expanded' , compactAiControlsOpen ? 'true' : 'false' )
167+ githubAiControls . dataset . compactOpen = compactAiControlsOpen ? 'true' : 'false'
168+ }
105169
106170const getCurrentLayout = ( ) => {
107171 if ( appGrid . classList . contains ( 'app-grid--preview-right' ) ) {
@@ -405,8 +469,6 @@ const {
405469 updateUiIssueIndicators,
406470} = diagnosticsUi
407471
408- const aiAssistantFeatureEnabled = isAiAssistantFeatureEnabled ( )
409-
410472const githubAiContextState = {
411473 token : null ,
412474 selectedRepository : null ,
@@ -1074,6 +1136,10 @@ for (const button of appGridLayoutButtons) {
10741136 }
10751137 applyAppGridLayout ( nextLayout )
10761138 applyPanelCollapseState ( )
1139+
1140+ if ( isStackedRailViewport ( ) ) {
1141+ setStackedRailViewControlsOpen ( false )
1142+ }
10771143 } )
10781144}
10791145
@@ -1084,9 +1150,72 @@ for (const button of appThemeButtons) {
10841150 return
10851151 }
10861152 applyTheme ( nextTheme )
1153+
1154+ if ( isStackedRailViewport ( ) ) {
1155+ setStackedRailViewControlsOpen ( false )
1156+ }
10871157 } )
10881158}
10891159
1160+ if ( viewControlsToggle instanceof HTMLButtonElement ) {
1161+ viewControlsToggle . addEventListener ( 'click' , ( ) => {
1162+ if ( ! isStackedRailViewport ( ) ) {
1163+ return
1164+ }
1165+
1166+ if ( isCompactViewport ( ) ) {
1167+ setCompactAiControlsOpen ( false )
1168+ }
1169+
1170+ setStackedRailViewControlsOpen ( ! stackedRailViewControlsOpen )
1171+ } )
1172+ }
1173+
1174+ if ( aiControlsToggle instanceof HTMLButtonElement ) {
1175+ aiControlsToggle . addEventListener ( 'click' , ( ) => {
1176+ if ( ! isCompactViewport ( ) ) {
1177+ return
1178+ }
1179+
1180+ setStackedRailViewControlsOpen ( false )
1181+ setCompactAiControlsOpen ( ! compactAiControlsOpen )
1182+ } )
1183+ }
1184+
1185+ document . addEventListener ( 'click' , event => {
1186+ const clickTarget = event . target
1187+ if ( ! ( clickTarget instanceof Node ) ) {
1188+ return
1189+ }
1190+
1191+ if ( isStackedRailViewport ( ) && stackedRailViewControlsOpen ) {
1192+ if (
1193+ ! viewControlsDrawer ?. contains ( clickTarget ) &&
1194+ ! viewControlsToggle ?. contains ( clickTarget )
1195+ ) {
1196+ setStackedRailViewControlsOpen ( false )
1197+ }
1198+ }
1199+
1200+ if ( isCompactViewport ( ) && compactAiControlsOpen ) {
1201+ if (
1202+ ! githubAiControls . contains ( clickTarget ) &&
1203+ ! aiControlsToggle ?. contains ( clickTarget )
1204+ ) {
1205+ setCompactAiControlsOpen ( false )
1206+ }
1207+ }
1208+ } )
1209+
1210+ document . addEventListener ( 'keydown' , event => {
1211+ if ( event . key !== 'Escape' ) {
1212+ return
1213+ }
1214+
1215+ setStackedRailViewControlsOpen ( false )
1216+ setCompactAiControlsOpen ( false )
1217+ } )
1218+
10901219for ( const button of editorToolsButtons ) {
10911220 button . addEventListener ( 'click' , ( ) => {
10921221 const panelName = button . dataset . editorToolsToggle
@@ -1112,6 +1241,11 @@ for (const button of panelCollapseButtons) {
11121241
11131242const handleCompactViewportChange = ( ) => {
11141243 applyPanelCollapseState ( )
1244+ setCompactAiControlsOpen ( false )
1245+ }
1246+
1247+ const handleStackedRailViewportChange = ( ) => {
1248+ setStackedRailViewControlsOpen ( false )
11151249}
11161250
11171251if ( typeof compactViewportMediaQuery . addEventListener === 'function' ) {
@@ -1120,6 +1254,12 @@ if (typeof compactViewportMediaQuery.addEventListener === 'function') {
11201254 compactViewportMediaQuery . onchange = handleCompactViewportChange
11211255}
11221256
1257+ if ( typeof stackedRailMediaQuery . addEventListener === 'function' ) {
1258+ stackedRailMediaQuery . addEventListener ( 'change' , handleStackedRailViewportChange )
1259+ } else {
1260+ stackedRailMediaQuery . onchange = handleStackedRailViewportChange
1261+ }
1262+
11231263window . addEventListener ( 'beforeunload' , ( ) => {
11241264 clearComponentLintRecheckTimer ( )
11251265 clearStylesLintRecheckTimer ( )
@@ -1131,6 +1271,8 @@ applyAppGridLayout(getInitialAppGridLayout(), { persist: false })
11311271applyTheme ( getInitialTheme ( ) , { persist : false } )
11321272applyEditorToolsVisibility ( )
11331273applyPanelCollapseState ( )
1274+ setStackedRailViewControlsOpen ( false )
1275+ setCompactAiControlsOpen ( false )
11341276syncAiChatTokenVisibility ( githubAiContextState . token )
11351277
11361278updateRenderButtonVisibility ( )
0 commit comments