Skip to content

Custom Panels And Vertical Panels ​

In Mantis extension docs, a custom panel and a vertical panel usually mean the same practical thing: a panel contributed by an extension and opened from the Verticals menu.

For fast iteration, you can build a vertical panel from a Mantis notebook first, then export it as a .mantisx package. Notebooks are useful as a prototyping environment because they let you pair Python setup code with a TSX UI cell and test the panel before turning it into a reusable extension. See Notebook-Based Extension Development.

How extension panels appear ​

An extension contributes panels through the manifest:

json
{
  "contributes": {
    "panels": [
      {
        "id": "pathwayInspector",
        "title": "Pathway Inspector",
        "entry": "dist/pathway-inspector.js",
        "styles": ["dist/pathway-inspector.css"]
      }
    ]
  }
}

After installation, Mantis shows the panel under:

text
Verticals > Extensions > Pathway Inspector

When the user selects it, Mantis opens the extension panel as a normal workspace tab.

If the extension manifest declares activationEvents: ["onPanel:pathwayInspector"], Mantis activates the extension host before rendering the panel.

The extension can also open its own contributed panels from host or panel code:

js
await mantis.panels.open('pathwayInspector');

This requires panels:write. The name may be the contributed panel id or title.

Multiple panels in one extension ​

One extension can contribute multiple panels:

json
{
  "contributes": {
    "panels": [
      {
        "id": "overview",
        "title": "Pathway Overview",
        "entry": "dist/overview.js",
        "styles": ["dist/shared.css"]
      },
      {
        "id": "details",
        "title": "Pathway Details",
        "entry": "dist/details.js",
        "styles": ["dist/shared.css"]
      }
    ]
  }
}

Use this when the panels belong to the same workflow, share permissions, or share backend code.

Single panel or multiple panels? ​

Use one panel when:

  • the workflow is focused
  • users should not switch between several extension tabs
  • the UI can fit naturally in one view

Use multiple panels when:

  • there are clearly separate tasks
  • each panel has a different screen shape
  • users may want to keep views open side by side

Panel ids and titles ​

id is the stable panel name. title is the user-facing label.

Good:

json
{
  "id": "geneSetExplorer",
  "title": "Gene Set Explorer"
}

Avoid changing panel ids after users begin using the extension. Saved layouts and open tabs may refer to the id.

Panel lifecycle ​

Panel JavaScript runs when the panel opens. If the user closes the panel, panel-local state is lost.

Use the extension host for behavior that should survive panel close. Store durable extension data with context.workspaceState for the current space or context.globalState for user-level state.

Communicating between panels ​

Panels can communicate indirectly through shared Mantis state, backend actions, or registered commands.

For durable commands, register handlers from the extension host:

Example:

js
exports.activate = async function activate(context) {
  context.subscriptions.push(
    await mantis.commands.registerCommand(
      'demo.workflow.refreshOverview',
      async () => {
        await refreshOverview();
      },
    ),
  );
};

A panel can call:

js
await window.mantis.commands.execute('demo.workflow.refreshOverview');

This requires commands:execute. If the manifest includes onCommand:demo.workflow.refreshOverview, Mantis activates the host before executing the command.

Design guidance ​

Extension panels should feel like part of Mantis:

  • keep controls compact
  • show errors clearly
  • avoid blocking the whole panel during long backend calls
  • use the same language as Mantis concepts: maps, points, selection, bags, panels
  • prefer explicit buttons for actions that write data
  • show what permissions or backend actions are being used when it helps users trust the result