Skip to main content

How to create Panels

In Phoenix Code, Panels are of two types :- Plugin Panel and Bottom Panel.

Plugin Panel appears on the side of the screen, generally the left side. For Example :- Live Preview feature uses the Plugin Panel.

Plugin Panel Example

Bottom Panel appears on the bottom of the screen as a tab. Multiple bottom panels share a tabbed interface where each panel gets its own tab with an icon and title. For Example :- Git, Terminal, Problems panel and many more use the Bottom Panel.

Bottom Panel Example

This document outlines the basic features of working with Panels.

Creating a Plugin Panel

To create a plugin panel, follow these steps:

  1. Import the WorkSpaceManager modules

    const WorkspaceManager = brackets.getModule("view/WorkspaceManager");
  2. Create panel content Create a jQuery object containing your panel's HTML content:

    const $panel = $("<div>")
    .attr("id", "my-extension-panel")
    .html("<h3>My Plugin Panel</h3><p>Hello from the panel!</p>");
  3. Create toolbar icon Create a toolbar icon to toggle the panel.

    Creating a toolbar icon is mandatory, else the panel won't show up.

  4. Create the plugin panel Use WorkspaceManager.createPluginPanel() to create your panel:

    const pluginPanel = WorkspaceManager.createPluginPanel(
    "myextension.panel", // Unique ID using package-style naming
    $panel, // jQuery object for panel content
    200, // minSize in pixels
    $toolbarIcon, // toolbar icon
    400 // initialSize in pixels (optional)
    );

For a detailed description, refer to this link.

Full Code Example:

define(function (require, exports, module) {
"use strict";

// Brackets modules
const AppInit = brackets.getModule("utils/AppInit"),
CommandManager = brackets.getModule("command/CommandManager"),
Menus = brackets.getModule("command/Menus"),
WorkspaceManager = brackets.getModule("view/WorkspaceManager");

let pluginPanel; // Store panel reference

// Function to run when the menu item is clicked
function handleTestExtension() {
if (!pluginPanel) {
// Create panel content
const $panel = $("<div>")
.attr("id", "my-extension-panel")
.html("<h3>My Plugin Panel</h3><p>Hello from the panel!</p>");

// Create toolbar icon
const $toolbarIcon = $("#panel");

// Create the plugin panel
pluginPanel = WorkspaceManager.createPluginPanel(
"myextension.panel",
$panel,
200,
$toolbarIcon,
400
);
pluginPanel.show();
}
}

// Register command
const MY_COMMAND_ID = "test_menuitem";
CommandManager.register("Toggle Panel", MY_COMMAND_ID, handleTestExtension);

// Add Menu item
const menu = Menus.getMenu(Menus.AppMenuBar.FILE_MENU);
menu.addMenuItem(MY_COMMAND_ID);

// Initialize extension
AppInit.appReady(function () {
console.log("Panel extension initialized");
});
});

Visual Reference Plugin Panel

Managing Plugin Panel State

You can control the visibility and state of your plugin panel:

  1. Show/Hide Panel

    // Show panel
    pluginPanel.show();

    // Hide panel
    pluginPanel.hide();
  2. Check Panel Visibility

    const isVisible = pluginPanel.isVisible();
  3. Toggle Panel Visibility

    function togglePanel() {
    if (pluginPanel.isVisible()) {
    pluginPanel.hide();
    } else {
    pluginPanel.show();
    }
    }

Creating a Bottom Panel

Bottom panels are created similarly to plugin panels but use different methods:

For Bottom Panels creating a toolbar icon is not required. Each bottom panel appears as a tab in the shared tab bar.

  1. Import required modules

    const WorkspaceManager = brackets.getModule("view/WorkspaceManager");
  2. Create the bottom panel

    const bottomPanel = WorkspaceManager.createBottomPanel(
    "myextension.panel", // Unique ID using package-style naming
    $panel, // jQuery object for panel content
    undefined, // minSize (deprecated, pass undefined)
    "My Panel", // Title shown on the tab
    {
    iconSvg: "path/to/icon.svg" // SVG icon for the tab
    }
    );
    • title: The text shown on the panel's tab. If not provided, Phoenix Code uses the text from a .toolbar .title element inside your panel, or derives it from the panel ID.
    • iconSvg: Path to an SVG file used as the tab icon. The icon automatically adapts to light and dark themes. If not provided, a default icon is used.

The minSize parameter (third argument) is deprecated and no longer used. Pass undefined for this parameter.

For a detailed description, refer to this link.

Full Code Example for Bottom Panel:

    define(function (require, exports, module) {
"use strict";

// Brackets modules
const AppInit = brackets.getModule("utils/AppInit"),
CommandManager = brackets.getModule("command/CommandManager"),
Menus = brackets.getModule("command/Menus"),
WorkspaceManager = brackets.getModule("view/WorkspaceManager");

let bottomPanel; // Store panel reference

// Function to run when the menu item is clicked
function handleTestExtension() {
if (!bottomPanel) {
// Create panel content
const $panel = $("<div>")
.attr("id", "my-extension-panel")
.html("<h3>My Bottom Panel</h3><p>Hello from the panel!</p>");

// Create the bottom panel
bottomPanel = WorkspaceManager.createBottomPanel(
"myextension.panel",
$panel,
undefined,
"My Panel",
{ iconSvg: "styles/images/panel-icon-default.svg" }
);
bottomPanel.show();
}
}

// Register command
const MY_COMMAND_ID = "test_menuitem";
CommandManager.register("Toggle Panel", MY_COMMAND_ID, handleTestExtension);

// Add Menu item
const menu = Menus.getMenu(Menus.AppMenuBar.FILE_MENU);
menu.addMenuItem(MY_COMMAND_ID);

// Initialize extension
AppInit.appReady(function () {
console.log("Panel extension initialized");
});
});

Visual Reference Bottom Panel

Managing Bottom Panel State

Bottom panels support similar state management to plugin panels:

  1. Show/Hide Panel

    // Show panel
    bottomPanel.show();

    // Hide panel
    bottomPanel.hide();
  2. Check Panel Visibility

    const isVisible = bottomPanel.isVisible();
  3. Toggle Panel Visibility

    function togglePanel() {
    if (bottomPanel.isVisible()) {
    bottomPanel.hide();
    } else {
    bottomPanel.show();
    }
    }
  4. Update Tab Title

    bottomPanel.setTitle("New Title");
  5. Handle Close Confirmation

    If your panel has unsaved state or running processes, you can register a handler that runs before the panel closes. Return false to prevent closing.

    bottomPanel.registerOnCloseRequestedHandler(async function () {
    if (hasUnsavedChanges) {
    const confirmed = await showConfirmDialog("Discard changes?");
    return confirmed; // true to close, false to cancel
    }
    return true;
    });

    To programmatically close a panel while respecting its close handler, use requestClose():

    const wasClosed = await bottomPanel.requestClose();

Best Practices

  1. Always use unique, package-style IDs (e.g., "yourextension.panel-name") to avoid conflicts with other extensions.

  2. Save panel state (e.g., visibility, size) in preferences if needed, to restore state when the extension is reloaded.

For more information about the WorkSpace Manager API, refer to the Phoenix Code API documentation.