From 48aba62297e5a2cde77042b2fbe781f18415fe37 Mon Sep 17 00:00:00 2001 From: Pluto Date: Fri, 24 Apr 2026 23:19:26 +0530 Subject: [PATCH 01/16] chore: add strings for playground file --- src/nls/root/strings.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/nls/root/strings.js b/src/nls/root/strings.js index 5e14c8d98d..756c4a0a75 100644 --- a/src/nls/root/strings.js +++ b/src/nls/root/strings.js @@ -2320,10 +2320,13 @@ define({ "DEMO_SECTION2_SUBTITLE": "Double-click to edit the text below and add your name", "DEMO_EDITABLE_PLACEHOLDER_HELLO": "Hello ___", "DEMO_SECTION2_SUCCESS_MESSAGE": "Your edit updated the code — undo with , redo with .", + "DEMO_SECTION2_TAG_HINT": "Click the text to select it — you'll see element controls appear above. Find the tag name span and change it to div.", + "DEMO_SECTION2_TAG_SUCCESS": "You changed the element's tag! You can also edit classes, IDs, and attributes this way.", "DEMO_HINT_COMPLETE_TASK_LABEL": "To complete this task:", "DEMO_SECTION2_HINT_STEP1": "Double-click on the \"Hello ___\" text", "DEMO_SECTION2_HINT_STEP2": "Replace the underscores with your name", "DEMO_SECTION2_HINT_STEP3": "Press Enter or click outside to apply your changes", + "DEMO_SECTION2_HINT_STEP4": "Click the text to select it — in the element controls above, change the span tag to div", "DEMO_SECTION3_TITLE": "Change images live", "DEMO_SECTION3_SUBTITLE": "Click the image below to replace it with one you like from the Image Library.", @@ -2359,6 +2362,8 @@ define({ "DEMO_SECTION6_SUBTITLE": "Select the \"Link\" icon in the toolbar to change where this link points.", "DEMO_LINK_EDIT_LINK": "Edit Link", "DEMO_SECTION6_SUCCESS_MESSAGE": "You edited a link.", + "DEMO_SECTION6_INSERT_HINT": "Now click \"Insert\" Insert Element in the toolbar and add an h3 heading.", + "DEMO_SECTION6_INSERT_SUCCESS": "You inserted a new element! You can add any HTML element to your page this way.", "DEMO_MODE_EXPLANATION_TITLE": "Edit mode vs Preview mode", "DEMO_EDIT_MODE_LABEL": "Edit mode", "DEMO_EDIT_MODE_DESCRIPTION": "Select and change things on the page", @@ -2369,6 +2374,7 @@ define({ "DEMO_SECTION6_TIP1": "Click any link to select it for editing", "DEMO_SECTION6_TIP2_NEWTAB": "Enable Open in new tab to open links on a separate page", "DEMO_SECTION6_TIP3_PREVIEW": "Switch to Preview mode (F8) to test links and interactions", + "DEMO_SECTION6_TIP4_INSERT": "Use the \"Insert\" Insert Element tool in the toolbar to add HTML elements to your page", "DEMO_COMPLETION_TITLE": "You're ready to build!", "DEMO_COMPLETION_BODY": "You've learned how to edit with Live Preview.
Open a folder with your HTML files to start editing.", From a9b41cd7ef5a6f9a404697acb3e895423e740522 Mon Sep 17 00:00:00 2001 From: Pluto Date: Sat, 25 Apr 2026 00:00:33 +0530 Subject: [PATCH 02/16] fix: quick access option gets stuck in selected state --- src/extensions/default/Git/src/Panel.js | 15 +++++++++++++++ .../CustomSnippets/main.js | 19 +++++++++++++++++++ .../DisplayShortcuts/main.js | 19 +++++++++++++++++++ src/view/DefaultPanelView.js | 5 +++-- src/view/PanelView.js | 12 +++++++++++- 5 files changed, 67 insertions(+), 3 deletions(-) diff --git a/src/extensions/default/Git/src/Panel.js b/src/extensions/default/Git/src/Panel.js index 41a509cbb5..8dee7b46a9 100644 --- a/src/extensions/default/Git/src/Panel.js +++ b/src/extensions/default/Git/src/Panel.js @@ -1510,6 +1510,21 @@ 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); + } + }); + + // 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); + } }); 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/view/DefaultPanelView.js b/src/view/DefaultPanelView.js index da4acd7944..7bc77680ac 100644 --- a/src/view/DefaultPanelView.js +++ b/src/view/DefaultPanelView.js @@ -198,12 +198,13 @@ define(function (require, exports, module) { } }); - // Update drawer button state when panels are shown. + // Update drawer button state based on bottom panel container visibility. + // The app drawer icon stays selected whenever the bottom panel is visible. PanelView.on(PanelView.EVENT_PANEL_SHOWN, function (event, panelID) { if (panelID === WorkspaceManager.DEFAULT_PANEL_ID) { _updateButtonVisibility(); } - $drawerBtn.toggleClass("selected-button", panelID === WorkspaceManager.DEFAULT_PANEL_ID); + $drawerBtn.addClass("selected-button"); }); PanelView.on(PanelView.EVENT_PANEL_HIDDEN, function (event, panelID) { diff --git a/src/view/PanelView.js b/src/view/PanelView.js index 6e9dcf8001..a3571dd580 100644 --- a/src/view/PanelView.js +++ b/src/view/PanelView.js @@ -899,8 +899,18 @@ define(function (require, exports, module) { // Maximize state is preserved so the panel re-opens maximized. _$tabBar.on("click", ".bottom-panel-hide-btn", function (e) { e.stopPropagation(); - if (_$container.is(":visible")) { + if (_$container && _$container.is(":visible")) { + if (_activeId) { + const activePanel = _panelMap[_activeId]; + if (activePanel) { + activePanel.$panel.removeClass("active-bottom-panel"); + } + } + _activeId = null; + _updateActiveTabHighlight(); + restoreIfMaximized(); Resizer.hide(_$container[0]); + exports.trigger(EVENT_PANEL_HIDDEN, _defaultPanelId); } }); From cb18c7ad7bdbc16c9a065b1a2f727c01256ae014 Mon Sep 17 00:00:00 2001 From: Pluto Date: Sat, 25 Apr 2026 00:15:15 +0530 Subject: [PATCH 03/16] fix: git is force opening the terminal on app reloads --- src/extensions/default/Git/src/Panel.js | 13 ++++++++++++- src/view/PanelView.js | 13 +++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/extensions/default/Git/src/Panel.js b/src/extensions/default/Git/src/Panel.js index 8dee7b46a9..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(); @@ -1515,6 +1524,7 @@ define(function (require, exports) { 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); } }); @@ -1524,6 +1534,7 @@ define(function (require, exports) { 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); } }); diff --git a/src/view/PanelView.js b/src/view/PanelView.js index a3571dd580..310b87c825 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 */ From 159267a65286307988bae3e475325b9974a6efa2 Mon Sep 17 00:00:00 2001 From: Pluto Date: Sat, 25 Apr 2026 00:22:24 +0530 Subject: [PATCH 04/16] feat: move back all the buttons to the right side in ai panel --- src/styles/Extn-AIChatPanel.less | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/styles/Extn-AIChatPanel.less b/src/styles/Extn-AIChatPanel.less index 60903bfdcd..10f73f8bd6 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; From 352e4ef1a97ac7281d12accc151539ec6ec0c406 Mon Sep 17 00:00:00 2001 From: Pluto Date: Sat, 25 Apr 2026 00:38:09 +0530 Subject: [PATCH 05/16] feat: add string for upload from device --- src/nls/root/strings.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nls/root/strings.js b/src/nls/root/strings.js index 756c4a0a75..d068424320 100644 --- a/src/nls/root/strings.js +++ b/src/nls/root/strings.js @@ -2268,6 +2268,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", From c3d07f097c0afbf11cdcf8231f9ed91d046bfa64 Mon Sep 17 00:00:00 2001 From: Pluto Date: Sat, 25 Apr 2026 00:43:01 +0530 Subject: [PATCH 06/16] feat: better close button color in the image option in ai panel --- src/styles/Extn-AIChatPanel.less | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/styles/Extn-AIChatPanel.less b/src/styles/Extn-AIChatPanel.less index 10f73f8bd6..e65503c6d4 100644 --- a/src/styles/Extn-AIChatPanel.less +++ b/src/styles/Extn-AIChatPanel.less @@ -1887,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 { From 9b0f6d28c17158773b0a7886b50b32fcd1b1f79d Mon Sep 17 00:00:00 2001 From: Pluto Date: Sat, 25 Apr 2026 00:53:36 +0530 Subject: [PATCH 07/16] chore: add missing string localization --- src/nls/root/strings.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nls/root/strings.js b/src/nls/root/strings.js index d068424320..d9bda2f0da 100644 --- a/src/nls/root/strings.js +++ b/src/nls/root/strings.js @@ -208,6 +208,7 @@ 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_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", From da2fb110e0b17e0856c1034b894de5b1634a637f Mon Sep 17 00:00:00 2001 From: Pluto Date: Sat, 25 Apr 2026 00:55:45 +0530 Subject: [PATCH 08/16] chore: update API docs --- docs/API-Reference/view/PanelView.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/API-Reference/view/PanelView.md b/docs/API-Reference/view/PanelView.md index 544969a668..852a6b9f63 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) From 9c6b70825d6225987ca0f1a235b23bf6699d60b1 Mon Sep 17 00:00:00 2001 From: Pluto Date: Sat, 25 Apr 2026 19:31:32 +0530 Subject: [PATCH 09/16] feat: add string for edit onboard feature --- src/nls/root/strings.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/nls/root/strings.js b/src/nls/root/strings.js index d9bda2f0da..f0e09efb7d 100644 --- a/src/nls/root/strings.js +++ b/src/nls/root/strings.js @@ -209,6 +209,11 @@ define({ "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", From 1e943a83f6e950e4e859ea07ef1055f22b31c557 Mon Sep 17 00:00:00 2001 From: Pluto Date: Sat, 25 Apr 2026 19:43:25 +0530 Subject: [PATCH 10/16] feat: remove playground file strings --- src/nls/root/strings.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/nls/root/strings.js b/src/nls/root/strings.js index f0e09efb7d..509a1f7e97 100644 --- a/src/nls/root/strings.js +++ b/src/nls/root/strings.js @@ -2327,13 +2327,10 @@ define({ "DEMO_SECTION2_SUBTITLE": "Double-click to edit the text below and add your name", "DEMO_EDITABLE_PLACEHOLDER_HELLO": "Hello ___", "DEMO_SECTION2_SUCCESS_MESSAGE": "Your edit updated the code — undo with , redo with .", - "DEMO_SECTION2_TAG_HINT": "Click the text to select it — you'll see element controls appear above. Find the tag name span and change it to div.", - "DEMO_SECTION2_TAG_SUCCESS": "You changed the element's tag! You can also edit classes, IDs, and attributes this way.", "DEMO_HINT_COMPLETE_TASK_LABEL": "To complete this task:", "DEMO_SECTION2_HINT_STEP1": "Double-click on the \"Hello ___\" text", "DEMO_SECTION2_HINT_STEP2": "Replace the underscores with your name", "DEMO_SECTION2_HINT_STEP3": "Press Enter or click outside to apply your changes", - "DEMO_SECTION2_HINT_STEP4": "Click the text to select it — in the element controls above, change the span tag to div", "DEMO_SECTION3_TITLE": "Change images live", "DEMO_SECTION3_SUBTITLE": "Click the image below to replace it with one you like from the Image Library.", @@ -2369,8 +2366,6 @@ define({ "DEMO_SECTION6_SUBTITLE": "Select the \"Link\" icon in the toolbar to change where this link points.", "DEMO_LINK_EDIT_LINK": "Edit Link", "DEMO_SECTION6_SUCCESS_MESSAGE": "You edited a link.", - "DEMO_SECTION6_INSERT_HINT": "Now click \"Insert\" Insert Element in the toolbar and add an h3 heading.", - "DEMO_SECTION6_INSERT_SUCCESS": "You inserted a new element! You can add any HTML element to your page this way.", "DEMO_MODE_EXPLANATION_TITLE": "Edit mode vs Preview mode", "DEMO_EDIT_MODE_LABEL": "Edit mode", "DEMO_EDIT_MODE_DESCRIPTION": "Select and change things on the page", @@ -2381,7 +2376,6 @@ define({ "DEMO_SECTION6_TIP1": "Click any link to select it for editing", "DEMO_SECTION6_TIP2_NEWTAB": "Enable Open in new tab to open links on a separate page", "DEMO_SECTION6_TIP3_PREVIEW": "Switch to Preview mode (F8) to test links and interactions", - "DEMO_SECTION6_TIP4_INSERT": "Use the \"Insert\" Insert Element tool in the toolbar to add HTML elements to your page", "DEMO_COMPLETION_TITLE": "You're ready to build!", "DEMO_COMPLETION_BODY": "You've learned how to edit with Live Preview.
Open a folder with your HTML files to start editing.", From abe0cc42433ca819466d3f7035a2bfdc95c252ce Mon Sep 17 00:00:00 2001 From: Pluto Date: Sat, 25 Apr 2026 23:48:04 +0530 Subject: [PATCH 11/16] feat: improve live preview resize ruler styling --- .../Phoenix-live-preview/live-preview.css | 36 +++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/src/extensionsIntegrated/Phoenix-live-preview/live-preview.css b/src/extensionsIntegrated/Phoenix-live-preview/live-preview.css index 98451f774e..e4af6987a8 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; From f141d70cc08a1024d436e6624089a7288955b710 Mon Sep 17 00:00:00 2001 From: Pluto Date: Sun, 26 Apr 2026 00:19:09 +0530 Subject: [PATCH 12/16] feat: use only chevron icon instead of full text for edit mode dropdown --- .../Phoenix-live-preview/live-preview.css | 86 ++++++++++++------- .../Phoenix-live-preview/main.js | 31 +++---- .../Phoenix-live-preview/panel.html | 12 ++- 3 files changed, 75 insertions(+), 54 deletions(-) diff --git a/src/extensionsIntegrated/Phoenix-live-preview/live-preview.css b/src/extensionsIntegrated/Phoenix-live-preview/live-preview.css index e4af6987a8..e4f64a51e5 100644 --- a/src/extensionsIntegrated/Phoenix-live-preview/live-preview.css +++ b/src/extensionsIntegrated/Phoenix-live-preview/live-preview.css @@ -370,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; @@ -422,7 +450,7 @@ flex-shrink: 0; } -#previewModeLivePreviewButton { +#designModeToggleLivePreviewButton { color: #a0a0a0; margin-left: 3px; margin-top: 0; @@ -431,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 @@ - - + + + +
From e067d0ee1c678468bcca0d7449b19ff636ae025b Mon Sep 17 00:00:00 2001 From: Pluto Date: Sun, 26 Apr 2026 00:43:45 +0530 Subject: [PATCH 13/16] build: update pro deps --- tracking-repos.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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" } } From 204b1c19424f4ea47616ac56646b1f9c5dd297b2 Mon Sep 17 00:00:00 2001 From: Pluto Date: Sun, 26 Apr 2026 01:38:24 +0530 Subject: [PATCH 14/16] feat: bottom panel doesnt open with the tab last closed --- src/view/DefaultPanelView.js | 11 ++++++-- src/view/PanelView.js | 54 ++++++++++++++++++++++++++---------- src/view/WorkspaceManager.js | 9 ++++-- 3 files changed, 54 insertions(+), 20 deletions(-) diff --git a/src/view/DefaultPanelView.js b/src/view/DefaultPanelView.js index 7bc77680ac..588f88b490 100644 --- a/src/view/DefaultPanelView.js +++ b/src/view/DefaultPanelView.js @@ -198,13 +198,18 @@ define(function (require, exports, module) { } }); - // Update drawer button state based on bottom panel container visibility. - // The app drawer icon stays selected whenever the bottom panel is visible. + // 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(); } - $drawerBtn.addClass("selected-button"); + $drawerBtn.toggleClass("selected-button", panelID === WorkspaceManager.DEFAULT_PANEL_ID); }); PanelView.on(PanelView.EVENT_PANEL_HIDDEN, function (event, panelID) { diff --git a/src/view/PanelView.js b/src/view/PanelView.js index 310b87c825..0dac9f5aef 100644 --- a/src/view/PanelView.js +++ b/src/view/PanelView.js @@ -908,23 +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 && _$container.is(":visible")) { - if (_activeId) { - const activePanel = _panelMap[_activeId]; - if (activePanel) { - activePanel.$panel.removeClass("active-bottom-panel"); - } - } - _activeId = null; - _updateActiveTabHighlight(); - restoreIfMaximized(); - Resizer.hide(_$container[0]); - exports.trigger(EVENT_PANEL_HIDDEN, _defaultPanelId); - } + collapseContainer(); }); // Maximize/restore toggle button @@ -1132,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[]} @@ -1226,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(); } From c1a335e0aea4317ae071003091c3e1a02cf67db8 Mon Sep 17 00:00:00 2001 From: Pluto Date: Sun, 26 Apr 2026 01:50:01 +0530 Subject: [PATCH 15/16] chore: auto update api docs --- docs/API-Reference/view/PanelView.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/API-Reference/view/PanelView.md b/docs/API-Reference/view/PanelView.md index 852a6b9f63..78d9eee962 100644 --- a/docs/API-Reference/view/PanelView.md +++ b/docs/API-Reference/view/PanelView.md @@ -312,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 From 5a8fd85bf4784a7f54c29ee7397043dc69dfc881 Mon Sep 17 00:00:00 2001 From: Pluto Date: Sun, 26 Apr 2026 16:09:21 +0530 Subject: [PATCH 16/16] fix: highlighting mode doesn't scroll the preview to select element --- .../BrowserScripts/RemoteFunctions.js | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) 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