diff --git a/docs/API-Reference/view/PanelView.md b/docs/API-Reference/view/PanelView.md index 544969a668..78d9eee962 100644 --- a/docs/API-Reference/view/PanelView.md +++ b/docs/API-Reference/view/PanelView.md @@ -141,6 +141,7 @@ Preference key for persisting the maximize state across reloads. * [.registerOnCloseRequestedHandler(handler)](#Panel+registerOnCloseRequestedHandler) * [.requestClose()](#Panel+requestClose) ⇒ Promise.<boolean> * [.show()](#Panel+show) + * [.addToTabBar()](#Panel+addToTabBar) * [.hide()](#Panel+hide) * [.focus()](#Panel+focus) ⇒ boolean * [.setVisible(visible)](#Panel+setVisible) @@ -206,6 +207,14 @@ registered, `hide()` is called. ### panel.show() Shows the panel +**Kind**: instance method of [Panel](#Panel) + + +### panel.addToTabBar() +Adds the panel to the tab bar and open set without showing the container. +Use this during startup to restore a panel's tab when the container +was collapsed by the user — avoids forcing the bottom panel open. + **Kind**: instance method of [Panel](#Panel) @@ -303,6 +312,26 @@ When the saved height is near-max or unknown, a sensible default is used. ## isMaximized() ⇒ boolean Returns true if the bottom panel is currently maximized. +**Kind**: global function + + +## collapseContainer() +Collapse the bottom panel container (transient hide) without touching +which panel is logically active. Fires EVENT_PANEL_HIDDEN with the +default panel id as a "container collapsed" signal so toolbar icons +and menu items that mirror container visibility deselect. +No-op if the container is already hidden. + +**Kind**: global function + + +## restoreContainer() +Re-show the bottom panel container after a previous collapse, with the +previously active panel still mounted. Fires EVENT_PANEL_SHOWN for the +active panel id so toolbar icons / menu items that mirror visibility +re-select. No-op if the container is already visible or there's no +active panel to restore. + **Kind**: global function diff --git a/src/LiveDevelopment/BrowserScripts/RemoteFunctions.js b/src/LiveDevelopment/BrowserScripts/RemoteFunctions.js index 81964e71c5..5fe5e77665 100644 --- a/src/LiveDevelopment/BrowserScripts/RemoteFunctions.js +++ b/src/LiveDevelopment/BrowserScripts/RemoteFunctions.js @@ -918,7 +918,9 @@ function RemoteFunctions(config = {}) { const nodes = window.document.querySelectorAll(rule); - // Highlight all matching nodes + // Highlight all matching nodes. selectElement() will narrow _clickHighlight + // down to the chosen element below; createCssSelectorHighlight() then + // re-highlights the siblings in a separate overlay. for (let i = 0; i < nodes.length; i++) { highlight(nodes[i]); } @@ -927,22 +929,23 @@ function RemoteFunctions(config = {}) { _clickHighlight.selector = rule; } - // In edit mode, select the best element and create temporary highlights for the rest. - // In highlight mode, skip selection so all matching elements stay highlighted equally. - if (config.mode === 'edit') { - const { element, skipSelection } = findBestElementToSelect(nodes, rule); - - if (!skipSelection) { - if (element) { - selectElement(element, true); - } else { - // No valid element found, dismiss UI - dismissUIAndCleanupState(); - } - } + // Both edit and highlight modes go through the same selection path: + // selectElement() handles scroll-to-view and the prominent click-highlight, + // createCssSelectorHighlight() shows siblings dimly. fromEditor=true + // suppresses tool-handler invocation, so highlight mode gets the + // highlighting/scroll behavior without any UI boxes. + const { element, skipSelection } = findBestElementToSelect(nodes, rule); - createCssSelectorHighlight(nodes, rule); + if (!skipSelection) { + if (element) { + selectElement(element, true); + } else { + // No valid element found, dismiss UI + dismissUIAndCleanupState(); + } } + + createCssSelectorHighlight(nodes, rule); } // recreate UI boxes so that they are placed properly diff --git a/src/extensions/default/Git/src/Panel.js b/src/extensions/default/Git/src/Panel.js index 41a509cbb5..d86d19692b 100644 --- a/src/extensions/default/Git/src/Panel.js +++ b/src/extensions/default/Git/src/Panel.js @@ -1358,7 +1358,16 @@ define(function (require, exports) { // Show gitPanel when appropriate if (Preferences.get("panelEnabled") && Setup.isExtensionActivated()) { - toggle(true); + // If the bottom panel container is collapsed, just add the Git tab + // without forcing it open. The user collapsed it intentionally. + const $container = $("#bottom-panel-container"); + if ($container.is(":visible")) { + toggle(true); + } else { + gitPanel.addToTabBar(); + $("#git-toolbar-icon").removeClass("forced-hidden"); + refresh(); + } } _panelResized(); GutterManager.init(); @@ -1510,6 +1519,23 @@ define(function (require, exports) { CommandManager.get(Constants.CMD_GIT_TOGGLE_PANEL).setChecked(false); Preferences.set("panelEnabled", false); } + // When the bottom panel container is collapsed, deselect the icon + // but don't save preference — the panel is still logically open. + if (panelID === WorkspaceManager.DEFAULT_PANEL_ID && Main.$icon) { + Main.$icon.toggleClass("on", false); + Main.$icon.toggleClass("selected-button", false); + CommandManager.get(Constants.CMD_GIT_TOGGLE_PANEL).setChecked(false); + } + }); + + // When any bottom panel is shown (container is visible), + // re-select the git icon if git panel is still open. + WorkspaceManager.on(WorkspaceManager.EVENT_WORKSPACE_PANEL_SHOWN, function (event, panelID) { + if (Main.$icon && Preferences.get("panelEnabled")) { + Main.$icon.toggleClass("on", true); + Main.$icon.toggleClass("selected-button", true); + CommandManager.get(Constants.CMD_GIT_TOGGLE_PANEL).setChecked(true); + } }); exports.init = init; diff --git a/src/extensionsIntegrated/CustomSnippets/main.js b/src/extensionsIntegrated/CustomSnippets/main.js index 3235942cba..e88122f448 100644 --- a/src/extensionsIntegrated/CustomSnippets/main.js +++ b/src/extensionsIntegrated/CustomSnippets/main.js @@ -255,14 +255,33 @@ define(function (require, exports, module) { }); } + // Track whether the snippets panel has an open tab (survives container collapse). + let _snippetsTabOpen = false; + // When the panel tab is closed externally (e.g. via the × button), // update the menu checked state to stay in sync. WorkspaceManager.on(WorkspaceManager.EVENT_WORKSPACE_PANEL_HIDDEN, function (event, panelID) { if (panelID === PANEL_ID && customSnippetsPanel) { + _snippetsTabOpen = false; + CommandManager.get(MY_COMMAND_ID).setChecked(false); + } + // Container collapsed — uncheck menu item but keep tab-open flag + if (panelID === WorkspaceManager.DEFAULT_PANEL_ID) { CommandManager.get(MY_COMMAND_ID).setChecked(false); } }); + // When any bottom panel is shown (container is visible), + // re-check menu item if snippets panel still has an open tab. + WorkspaceManager.on(WorkspaceManager.EVENT_WORKSPACE_PANEL_SHOWN, function (event, panelID) { + if (panelID === PANEL_ID) { + _snippetsTabOpen = true; + } + if (_snippetsTabOpen) { + CommandManager.get(MY_COMMAND_ID).setChecked(true); + } + }); + AppInit.appReady(function () { CommandManager.register(MENU_ITEM_NAME, MY_COMMAND_ID, showCustomSnippetsPanel); // Render template with localized strings diff --git a/src/extensionsIntegrated/DisplayShortcuts/main.js b/src/extensionsIntegrated/DisplayShortcuts/main.js index 3c71d6b0c2..330ccb4225 100644 --- a/src/extensionsIntegrated/DisplayShortcuts/main.js +++ b/src/extensionsIntegrated/DisplayShortcuts/main.js @@ -539,14 +539,33 @@ define(function (require, exports, module) { KeyBindingManager.on(KeyBindingManager.EVENT_NEW_PRESET, _updatePresets); KeyBindingManager.on(KeyBindingManager.EVENT_PRESET_CHANGED, _updatePresets); + // Track whether the shortcuts panel has an open tab (survives container collapse). + let _shortcutsTabOpen = false; + // When the panel tab is closed externally (e.g. via the × button), // update the menu checked state and clean up resources. WorkspaceManager.on(WorkspaceManager.EVENT_WORKSPACE_PANEL_HIDDEN, function (event, panelID) { if (panelID === TOGGLE_SHORTCUTS_ID && panel) { + _shortcutsTabOpen = false; destroyKeyList(); _clearSortingEventHandlers(); CommandManager.get(TOGGLE_SHORTCUTS_ID).setChecked(false); } + // Container collapsed — uncheck menu item but keep tab-open flag + if (panelID === WorkspaceManager.DEFAULT_PANEL_ID) { + CommandManager.get(TOGGLE_SHORTCUTS_ID).setChecked(false); + } + }); + + // When any bottom panel is shown (container is visible), + // re-check menu item if shortcuts panel still has an open tab. + WorkspaceManager.on(WorkspaceManager.EVENT_WORKSPACE_PANEL_SHOWN, function (event, panelID) { + if (panelID === TOGGLE_SHORTCUTS_ID) { + _shortcutsTabOpen = true; + } + if (_shortcutsTabOpen) { + CommandManager.get(TOGGLE_SHORTCUTS_ID).setChecked(true); + } }); }); }); diff --git a/src/extensionsIntegrated/Phoenix-live-preview/live-preview.css b/src/extensionsIntegrated/Phoenix-live-preview/live-preview.css index 98451f774e..e4f64a51e5 100644 --- a/src/extensionsIntegrated/Phoenix-live-preview/live-preview.css +++ b/src/extensionsIntegrated/Phoenix-live-preview/live-preview.css @@ -155,22 +155,48 @@ transform: translateX(-50%); z-index: 10; display: none; - padding: 6px 16px; + padding: 6px 14px; border-radius: 6px; background: rgba(0, 0, 0, 0.88); border: 1px solid rgba(255, 255, 255, 0.18); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); color: #fff; - font-size: 15px; + font-size: 13px; font-weight: 600; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; white-space: nowrap; pointer-events: none; - letter-spacing: 0.5px; + letter-spacing: 0.3px; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.06); } +.responsive-dimension-label .responsive-dimension-device { + color: rgba(255, 255, 255, 0.7); + font-weight: 400; +} + +.responsive-dimension-label .responsive-dimension-device i { + margin-right: 5px; + font-size: 11px; + vertical-align: middle; +} + +.responsive-dimension-label .responsive-dimension-name { + vertical-align: middle; +} + +.responsive-dimension-label .responsive-dimension-separator { + color: rgba(255, 255, 255, 0.35); + margin: 0 6px; + font-weight: 400; +} + +.responsive-dimension-label .responsive-dimension-size { + color: #fff; + font-weight: 600; +} + .plugin-toolbar { height: var(--toolbar-height); color: #a0a0a0; @@ -321,6 +347,10 @@ font-size: inherit; } +.device-size-item-icon-fit { + font-size: 11px; +} + .device-size-item-row { display: flex; justify-content: space-between; @@ -340,50 +370,78 @@ color: rgba(100, 180, 255, 0.8); } -#livePreviewModeBtn { - min-width: fit-content; +.lp-mode-btn-group { display: flex; align-items: center; + flex-shrink: 0; margin: 0 4px 0 3px; - max-width: 80%; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - cursor: pointer; - background: transparent; - box-shadow: none; border: 1px solid transparent; + border-radius: 3px; box-sizing: border-box; +} + +.lp-mode-btn-group:hover { + border-color: rgba(255, 255, 255, 0.1); +} + +.lp-mode-icon { + display: flex; + align-items: center; + justify-content: center; + width: 22px; + height: 22px; + cursor: pointer; + background: transparent; + box-shadow: none !important; + border: none; color: #a0a0a0; - font-size: 14px; - font-weight: normal; - padding: 0 0.35em; + padding: 0; + margin: 0; } -#livePreviewModeBtn:hover, -#livePreviewModeBtn:focus, -#livePreviewModeBtn:active { +#live-preview-plugin-toolbar .lp-mode-icon:hover, +#live-preview-plugin-toolbar .lp-mode-icon:focus, +#live-preview-plugin-toolbar .lp-mode-icon:active { background: transparent !important; - border: 1px solid rgba(255, 255, 255, 0.1) !important; + border: none !important; box-shadow: none !important; } -#livePreviewModeBtn.btn-dropdown::after { - position: static; - margin-top: 2px; - margin-left: 5px; +.lp-mode-icon.selected { + color: #FBB03B; } -#reloadLivePreviewButton { +.lp-mode-dropdown-chevron { + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + background: transparent; + box-shadow: none !important; + border: none; + border-left: 1px solid transparent; + border-radius: 0 3px 3px 0; color: #a0a0a0; - margin-left: 3px; - margin-top: 0; - width: 30px; + padding: 0 4px; + margin: 0; height: 22px; - flex-shrink: 0; + font-size: 10px; } -#designModeToggleLivePreviewButton { +.lp-mode-btn-group:hover .lp-mode-dropdown-chevron { + border-left-color: rgba(255, 255, 255, 0.1); +} + +#live-preview-plugin-toolbar .lp-mode-dropdown-chevron:hover, +#live-preview-plugin-toolbar .lp-mode-dropdown-chevron:focus, +#live-preview-plugin-toolbar .lp-mode-dropdown-chevron:active { + background: transparent !important; + border: none !important; + border-left: 1px solid rgba(255, 255, 255, 0.1) !important; + box-shadow: none !important; +} + +#reloadLivePreviewButton { color: #a0a0a0; margin-left: 3px; margin-top: 0; @@ -392,7 +450,7 @@ flex-shrink: 0; } -#previewModeLivePreviewButton { +#designModeToggleLivePreviewButton { color: #a0a0a0; margin-left: 3px; margin-top: 0; @@ -401,10 +459,6 @@ flex-shrink: 0; } -#previewModeLivePreviewButton.selected{ - color: #FBB03B; -} - .live-preview-status-overlay { display: flex; flex-direction: row; diff --git a/src/extensionsIntegrated/Phoenix-live-preview/main.js b/src/extensionsIntegrated/Phoenix-live-preview/main.js index e83743ea01..c2bbaafa18 100644 --- a/src/extensionsIntegrated/Phoenix-live-preview/main.js +++ b/src/extensionsIntegrated/Phoenix-live-preview/main.js @@ -169,6 +169,7 @@ define(function (require, exports, module) { $firefoxButtonBallast, $panelTitle, $modeBtn, + $modeBtnGroup, $previewBtn, $designModeBtn; @@ -343,26 +344,19 @@ define(function (require, exports, module) { */ function _updateLPControlsForMdviewer() { const inDesignMode = WorkspaceManager.isInDesignMode && WorkspaceManager.isInDesignMode(); + const showPen = !_isMdviewrActive; + // Dropdown is also hidden in design mode (see $designModeBtn wiring in + // _createExtensionPanel) because the preview-mode options are moot + // when the editor is fully collapsed. + const showChevron = !_isMdviewrActive && !inDesignMode; if ($previewBtn) { - $previewBtn.toggle(!_isMdviewrActive); + $previewBtn.toggle(showPen); } if ($modeBtn) { - // Also hidden in design mode (see $designModeBtn wiring in - // _createExtensionPanel) because the preview-mode dropdown is moot - // when the editor is fully collapsed. - $modeBtn.toggle(!_isMdviewrActive && !inDesignMode); + $modeBtn.toggle(showChevron); } - } - - function _updateModeButton(mode) { - if ($modeBtn) { - if (mode === "highlight") { - $modeBtn[0].textContent = Strings.LIVE_PREVIEW_MODE_HIGHLIGHT; - } else if (mode === "edit") { - $modeBtn[0].textContent = Strings.LIVE_PREVIEW_MODE_EDIT; - } else { - $modeBtn[0].textContent = Strings.LIVE_PREVIEW_MODE_PREVIEW; - } + if ($modeBtnGroup && $modeBtnGroup.length) { + $modeBtnGroup.toggle(showPen || showChevron); } } @@ -371,14 +365,12 @@ define(function (require, exports, module) { // Pencil button lights up only when edit mode is active; preview / // highlight modes leave it un-tinted. Click toggles between edit - // and preview. + // and preview. The chevron next to it opens the full mode dropdown. if (currentMode === LiveDevelopment.CONSTANTS.LIVE_EDIT_MODE) { $previewBtn.addClass('selected'); } else { $previewBtn.removeClass('selected'); } - - _updateModeButton(currentMode); } function _showModeSelectionDropdown(event) { @@ -809,6 +801,7 @@ define(function (require, exports, module) { $panelTitle = $panel.find("#panel-live-preview-title"); $settingsIcon = $panel.find("#livePreviewSettingsBtn"); $modeBtn = $panel.find("#livePreviewModeBtn"); + $modeBtnGroup = $panel.find("#lpModeBtnGroup"); $previewBtn = $panel.find("#previewModeLivePreviewButton"); $designModeBtn = $panel.find("#designModeToggleLivePreviewButton"); diff --git a/src/extensionsIntegrated/Phoenix-live-preview/panel.html b/src/extensionsIntegrated/Phoenix-live-preview/panel.html index d62408e8f7..f6c33b3e34 100644 --- a/src/extensionsIntegrated/Phoenix-live-preview/panel.html +++ b/src/extensionsIntegrated/Phoenix-live-preview/panel.html @@ -7,10 +7,14 @@ - - + + + +
diff --git a/src/nls/root/strings.js b/src/nls/root/strings.js index 5e14c8d98d..509a1f7e97 100644 --- a/src/nls/root/strings.js +++ b/src/nls/root/strings.js @@ -208,6 +208,12 @@ define({ "LIVE_DEV_INSERT_NO_RESULTS": "No matching elements", "LIVE_DEV_INSERT_SEE_MORE": "See more", "LIVE_DEV_INSERT_SHOW_LESS": "Show less", + "LIVE_DEV_INSERT_CREATE": "Create", + "LIVE_DEV_EDIT_ONBOARD_TITLE": "Two new ways to edit", + "LIVE_DEV_EDIT_ONBOARD_INSERT": "Add new HTML elements", + "LIVE_DEV_EDIT_ONBOARD_PROPS": "Edit tag, classes, ID and attributes", + "LIVE_DEV_EDIT_ONBOARD_GOT_IT": "Got it", + "LIVE_DEV_EDIT_ONBOARD_READ_DOCS": "Read docs", "LIVE_DEV_IMAGE_GALLERY_USE_IMAGE": "Download image", "LIVE_DEV_IMAGE_GALLERY_SELECT_DOWNLOAD_FOLDER": "Choose image download folder", "LIVE_DEV_IMAGE_GALLERY_SEARCH_PLACEHOLDER": "Search images\u2026", @@ -2268,6 +2274,7 @@ define({ "AI_CHAT_SCREENSHOT_SELECTED_ELEMENT": "Live Preview Selection", "AI_CHAT_SCREENSHOT_CAPTURE": "Capture", "AI_CHAT_SCREENSHOT_CANCEL": "Cancel", + "AI_CHAT_SCREENSHOT_UPLOAD": "Upload from Device", "AI_CHAT_PRIVACY_TITLE": "Start AI Chat with Claude Code", "AI_CHAT_PRIVACY_BODY": "To provide responses, this feature sends your prompts and relevant context to Claude Code.

Learn more and manage your privacy settings.", "AI_CHAT_PRIVACY_OK": "OK", diff --git a/src/styles/Extn-AIChatPanel.less b/src/styles/Extn-AIChatPanel.less index 60903bfdcd..e65503c6d4 100644 --- a/src/styles/Extn-AIChatPanel.less +++ b/src/styles/Extn-AIChatPanel.less @@ -77,9 +77,9 @@ line-height: 19px; } - .ai-chat-header-actions, - .ai-chat-header-left-actions { + .ai-chat-header-actions { position: absolute; + right: 10px; display: flex; align-items: center; gap: 2px; @@ -88,14 +88,6 @@ transition: opacity 0.5s ease; } - .ai-chat-header-actions { - right: 10px; - } - - .ai-chat-header-left-actions { - left: 10px; - } - .ai-history-btn, .ai-settings-btn { display: flex; @@ -121,8 +113,7 @@ } /* Show header actions on tab container hover */ -.ai-tab-container:hover .ai-chat-header-actions, -.ai-tab-container:hover .ai-chat-header-left-actions { +.ai-tab-container:hover .ai-chat-header-actions { opacity: 1; pointer-events: auto; transition: opacity 0.15s ease; @@ -1896,31 +1887,28 @@ .ai-image-remove { position: absolute; - top: -6px; - right: -6px; - width: 16px; - height: 16px; + top: -8px; + right: -8px; + width: 20px; + height: 20px; border-radius: 50%; - background: rgba(255, 255, 255, 0.12); - border: 1px solid rgba(255, 255, 255, 0.18); - color: rgba(255, 255, 255, 0.7); - font-size: 11px; + background: rgba(0, 0, 0, 0.6); + border: 1px solid rgba(255, 255, 255, 0.3); + color: #fff; + font-size: 12px; + line-height: 1; padding: 0; - display: none; + display: flex; align-items: center; justify-content: center; cursor: pointer; transition: background 150ms, color 150ms; &:hover { - background: rgba(255, 255, 255, 0.22); + background: rgba(255, 255, 255, 0.25); color: #fff; } } - - &:hover .ai-image-remove { - display: flex; - } } .ai-file-chip { diff --git a/src/view/DefaultPanelView.js b/src/view/DefaultPanelView.js index da4acd7944..588f88b490 100644 --- a/src/view/DefaultPanelView.js +++ b/src/view/DefaultPanelView.js @@ -198,7 +198,13 @@ define(function (require, exports, module) { } }); - // Update drawer button state when panels are shown. + // Drawer button reflects whether the Quick Access (default) panel is + // the active visible panel. _switchToTab silently swaps active tabs + // without firing PANEL_HIDDEN for the previous one, so we have to gate + // the SHOWN handler on the panelID — relying on a HIDDEN event would + // miss the case where another tab takes over from Quick Access. + // The minimize-button "stuck selected" case is handled by PanelView + // firing PANEL_HIDDEN with the default panel id, picked up below. PanelView.on(PanelView.EVENT_PANEL_SHOWN, function (event, panelID) { if (panelID === WorkspaceManager.DEFAULT_PANEL_ID) { _updateButtonVisibility(); diff --git a/src/view/PanelView.js b/src/view/PanelView.js index 6e9dcf8001..0dac9f5aef 100644 --- a/src/view/PanelView.js +++ b/src/view/PanelView.js @@ -731,6 +731,19 @@ define(function (require, exports, module) { exports.trigger(EVENT_PANEL_SHOWN, panelId); }; + /** + * Adds the panel to the tab bar and open set without showing the container. + * Use this during startup to restore a panel's tab when the container + * was collapsed by the user — avoids forcing the bottom panel open. + */ + Panel.prototype.addToTabBar = function () { + if (!_$container || _openIds.indexOf(this.panelID) !== -1) { + return; + } + _openIds.push(this.panelID); + _addTabToBar(this.panelID); + }; + /** * Hides the panel */ @@ -895,13 +908,12 @@ define(function (require, exports, module) { _showOverflowMenu(); }); - // Hide-panel button collapses the container but keeps tabs intact. - // Maximize state is preserved so the panel re-opens maximized. + // Hide-panel button collapses the container but keeps the active + // panel logically active so re-opening (drawer / Escape) restores it + // with its content already mounted. _$tabBar.on("click", ".bottom-panel-hide-btn", function (e) { e.stopPropagation(); - if (_$container.is(":visible")) { - Resizer.hide(_$container[0]); - } + collapseContainer(); }); // Maximize/restore toggle button @@ -1109,6 +1121,39 @@ define(function (require, exports, module) { return _isMaximized; } + /** + * Collapse the bottom panel container (transient hide) without touching + * which panel is logically active. Fires EVENT_PANEL_HIDDEN with the + * default panel id as a "container collapsed" signal so toolbar icons + * and menu items that mirror container visibility deselect. + * No-op if the container is already hidden. + */ + function collapseContainer() { + if (!_$container || !_$container.is(":visible")) { + return; + } + restoreIfMaximized(); + Resizer.hide(_$container[0]); + exports.trigger(EVENT_PANEL_HIDDEN, _defaultPanelId); + } + + /** + * Re-show the bottom panel container after a previous collapse, with the + * previously active panel still mounted. Fires EVENT_PANEL_SHOWN for the + * active panel id so toolbar icons / menu items that mirror visibility + * re-select. No-op if the container is already visible or there's no + * active panel to restore. + */ + function restoreContainer() { + if (!_$container || _$container.is(":visible")) { + return; + } + Resizer.show(_$container[0]); + if (_activeId) { + exports.trigger(EVENT_PANEL_SHOWN, _activeId); + } + } + /** * Returns a copy of the currently open bottom panel IDs in tab order. * @return {string[]} @@ -1203,6 +1248,8 @@ define(function (require, exports, module) { exports.restoreIfMaximized = restoreIfMaximized; exports.isMaximized = isMaximized; exports.MAXIMIZE_THRESHOLD = MAXIMIZE_THRESHOLD; + exports.collapseContainer = collapseContainer; + exports.restoreContainer = restoreContainer; //events exports.EVENT_PANEL_HIDDEN = EVENT_PANEL_HIDDEN; exports.EVENT_PANEL_SHOWN = EVENT_PANEL_SHOWN; diff --git a/src/view/WorkspaceManager.js b/src/view/WorkspaceManager.js index de4ca2b8c3..d695390eec 100644 --- a/src/view/WorkspaceManager.js +++ b/src/view/WorkspaceManager.js @@ -812,9 +812,14 @@ define(function (require, exports, module) { return false; } if ($bottomPanelContainer.is(":visible")) { - Resizer.hide($bottomPanelContainer[0]); + // Use the helper so HIDDEN(_defaultPanelId) fires — toolbar + // buttons and menu items that mirror container visibility + // (drawer, Git icon, etc.) need this signal to deselect. + PanelView.collapseContainer(); } else if (PanelView.getOpenBottomPanelIDs().length > 0) { - Resizer.show($bottomPanelContainer[0]); + // Use the helper so SHOWN(_activeId) fires — same listeners + // need this signal to re-select after a previous collapse. + PanelView.restoreContainer(); } else { _showDefaultPanel(); } diff --git a/tracking-repos.json b/tracking-repos.json index b883c1d8bc..ca92efe992 100644 --- a/tracking-repos.json +++ b/tracking-repos.json @@ -1,5 +1,5 @@ { "phoenixPro": { - "commitID": "4749d2e7bbdbe93f5f4c270212b30b02061c0d7b" + "commitID": "2ab18a599da4872d5519841b6b222dea7c321ac3" } }