侧边栏标签页 API 允许扩展为 ComfyUI 界面的侧边栏添加自定义标签页。这对于添加需要持续可见性和快速访问的功能非常有用。

基本用法

app.extensionManager.registerSidebarTab({
  id: "customSidebar",
  icon: "pi pi-compass",
  title: "自定义标签页",
  tooltip: "我的自定义侧边栏标签页",
  type: "custom",
  render: (el) => {
    el.innerHTML = '<div>这是我的自定义侧边栏内容</div>';
  }
});

标签页配置

每个标签页需要以下属性:

{
  id: string,              // 标签页的唯一标识符
  icon: string,            // 标签按钮的图标类名
  title: string,           // 标签页标题文本
  tooltip?: string,        // 悬停时的提示文本(可选)
  type: string,            // 标签页类型(通常为 "custom")
  render: (element) => void // 用于填充标签页内容的函数
}

render 函数会接收一个 DOM 元素,你应在其中插入标签页的内容。

图标选项

侧边栏标签页图标可使用多种图标集:

  • PrimeVue 图标:pi pi-[icon-name](如 pi pi-home
  • Material Design 图标:mdi mdi-[icon-name](如 mdi mdi-robot
  • Font Awesome 图标:fa-[style] fa-[icon-name](如 fa-solid fa-star

使用这些图标前请确保已加载相应的图标库。

有状态标签页示例

你可以创建带有状态的标签页:

app.extensionManager.registerSidebarTab({
  id: "statefulTab",
  icon: "pi pi-list",
  title: "笔记",
  type: "custom",
  render: (el) => {
    // 创建元素
    const container = document.createElement('div');
    container.style.padding = '10px';
    
    const notepad = document.createElement('textarea');
    notepad.style.width = '100%';
    notepad.style.height = '200px';
    notepad.style.marginBottom = '10px';
    
    // 加载已保存内容(如有)
    const savedContent = localStorage.getItem('comfyui-notes');
    if (savedContent) {
      notepad.value = savedContent;
    }
    
    // 自动保存内容
    notepad.addEventListener('input', () => {
      localStorage.setItem('comfyui-notes', notepad.value);
    });
    
    // 组装 UI
    container.appendChild(notepad);
    el.appendChild(container);
  }
});

使用 React 组件

你可以在侧边栏标签页中挂载 React 组件:

// 在你的扩展中引入 React 依赖
import React from "react";
import ReactDOM from "react-dom/client";

// 注册带有 React 内容的侧边栏标签页
app.extensionManager.registerSidebarTab({
  id: "reactSidebar",
  icon: "mdi mdi-react",
  title: "React 标签页",
  type: "custom",
  render: (el) => {
    const container = document.createElement("div");
    container.id = "react-sidebar-container";
    el.appendChild(container);
    
    // 定义一个简单的 React 组件
    function SidebarContent() {
      const [count, setCount] = React.useState(0);
      
      return (
        <div style={{ padding: "10px" }}>
          <h3>React 侧边栏</h3>
          <p>计数:{count}</p>
          <button onClick={() => setCount(count + 1)}>
            递增
          </button>
        </div>
      );
    }
    
    // 挂载 React 组件
    ReactDOM.createRoot(container).render(
      <React.StrictMode>
        <SidebarContent />
      </React.StrictMode>
    );
  }
});

如需查看将 React 应用集成为侧边栏标签页的真实案例,请参考 ComfyUI-Copilot 项目(GitHub)

动态内容更新

你可以根据图变化动态更新侧边栏内容:

app.extensionManager.registerSidebarTab({
  id: "dynamicSidebar",
  icon: "pi pi-chart-line",
  title: "统计信息",
  type: "custom",
  render: (el) => {
    const container = document.createElement('div');
    container.style.padding = '10px';
    el.appendChild(container);
    
    // 更新统计信息的函数
    function updateStats() {
      const stats = {
        nodes: app.graph._nodes.length,
        connections: Object.keys(app.graph.links).length
      };
      
      container.innerHTML = `
        <h3>工作流统计</h3>
        <ul>
          <li>节点数:${stats.nodes}</li>
          <li>连接数:${stats.connections}</li>
        </ul>
      `;
    }
    
    // 初始更新
    updateStats();
    
    // 监听图变化
    const api = app.api;
    api.addEventListener("graphChanged", updateStats);
    
    // 标签页销毁时清理监听器
    return () => {
      api.removeEventListener("graphChanged", updateStats);
    };
  }
});