@e-llm-studio/creative-workspace-ui-component

中文文档
0.0.69发布于 2026/10/28MITTypeScriptESM + CJS近 30 天下载 2661

Reusable React components for Creative Workspace.

原始使用文档
文档目录38 节
  1. Introduction
  2. Features
  3. Installation
  4. Using npm
  5. Using yarn
  6. Import Statement
  7. Usage
  8. Basic Example
  9. Advanced Example
  10. API Reference
  11. Props
  12. TreeSectionConfig
  13. NodeTypeConfig
  14. ScopeTreeNode
  15. Type Definitions
  16. Examples
  17. With search
  18. With only rename and delete (no add)
  19. With badges hidden
  20. With auto-selected node
  21. With multiple sections
  22. Notes
  23. Features
  24. Installation
  25. Public exports
  26. Props
  27. Core Types
  28. MetaData
  29. Level
  30. AssigneeUser
  31. SavePayload
  32. Included Components
  33. AssignReminderLevels
  34. ReviewStatus
  35. LevelData
  36. UI Components
  37. Basic usage
  38. Key capabilities

TreeSidebar Component

A hierarchical tree navigation component for rendering nested scope/node structures with expandable sections, search, and configurable actions. The component is part of the @e-llm-studio/creative-workspace-ui-component package and can be used independently in any React application.


Introduction

TreeSidebar is a standalone component from the @e-llm-studio/creative-workspace-ui-component package designed to provide a fully generic, hierarchical tree navigation panel. Its primary purpose is to render a tree of nodes (e.g. Global → Scope → Subscope) with expandable sections, search filtering, and optional action handlers. The consuming team controls what actions are available by passing or omitting handler props — if a handler is not passed, the corresponding button is not rendered.


Features

  • Hierarchical tree rendering — Supports unlimited nesting levels (Global → Scope → Subscope → ...)
  • Expand/collapse — Each node is independently expandable; root node auto-expands on load
  • Section items — Each node can show configurable section tabs (e.g. Learnings, Stations) below it when expanded
  • Search filtering — Pass a searchQuery to filter nodes by name; non-matching subtrees are hidden
  • Configurable node types — Control labels, add-child labels and child types via nodeTypesConfig
  • Configurable sections — Control which sections appear per node via sectionsConfig
  • Conditional actions — Add, Rename, Delete buttons only render when the corresponding handler prop is passed
  • Children count badge — Optional badge showing number of direct children per node
  • Section badge — Optional badge on section items showing metrics (e.g. learnings count)
  • Inline styles only — No Tailwind or MUI dependency, works in any consuming app regardless of styling setup

Installation

The TreeSidebar component is part of the @e-llm-studio/creative-workspace-ui-component package.

Using npm

npm install @e-llm-studio/creative-workspace-ui-component

Using yarn

yarn add @e-llm-studio/creative-workspace-ui-component

Import Statement

import { TreeSidebar } from "@e-llm-studio/creative-workspace-ui-component";
// or via subpath
import { TreeSidebar } from "@e-llm-studio/creative-workspace-ui-component/TreeSidebar";

Usage

Basic Example

Here's a simple example demonstrating how to use TreeSidebar with minimal props:

import { TreeSidebar } from "@e-llm-studio/creative-workspace-ui-component";
import { BookOpen } from "lucide-react";

const treeData = {
  id: "root",
  name: "Global Scope",
  type: "GLOBAL" as const,
  metrics: { learningsCount: 10 },
  children: [
    {
      id: "scope-1",
      name: "Scope 1",
      type: "SCOPE" as const,
      metrics: { learningsCount: 5 },
      children: [],
    },
  ],
};

export default function App() {
  return (
    <TreeSidebar
      data={treeData}
      sectionsConfig={[
        {
          id: "learnings",
          label: "Learnings",
          icon: BookOpen,
          badgeKey: "learningsCount",
        },
      ]}
      nodeTypesConfig={[
        { type: "GLOBAL", label: "Global", addChildLabel: "Add Scope", addChildType: "SCOPE" },
        { type: "SCOPE", label: "Scope" },
      ]}
      onSectionSelect={(nodeId, sectionId) => console.log(nodeId, sectionId)}
    />
  );
}

Key Props Explained:

  • data: The root node of the tree — pass null to render nothing
  • sectionsConfig: Defines which section tabs appear under each expanded node
  • nodeTypesConfig: Defines node labels and add-child behavior per depth level
  • onSectionSelect: Fired when a section tab is clicked — returns the selected nodeId and sectionId

Advanced Example

This example demonstrates all action handlers and badge visibility controls:

import { TreeSidebar } from "@e-llm-studio/creative-workspace-ui-component";
import { BookOpen } from "lucide-react";

export default function AdvancedExample() {
  return (
    <TreeSidebar
      data={treeData}
      sectionsConfig={[
        {
          id: "learnings",
          label: "Learnings",
          icon: BookOpen,
          badgeKey: "learningsCount",
        },
      ]}
      nodeTypesConfig={[
        { type: "GLOBAL", label: "Global", addChildLabel: "Add Scope", addChildType: "SCOPE" },
        { type: "SCOPE", label: "Scope" },
      ]}
      onSectionSelect={(nodeId, sectionId) => handleSelect(nodeId, sectionId)}
      onAddChild={(parentId, childType, parentName) => handleAdd(parentId, childType, parentName)}
      onRenameChild={(scopeId, initialName) => handleRename(scopeId, initialName)}
      onDeleteChild={(scopeId, scopeName, learningsCount) => handleDelete(scopeId, scopeName, learningsCount)}
      showChildrenCount={true}
      showSectionBadge={true}
    />
  );
}

Customization Tips:

  • Only pass the action handlers (onAddChild, onRenameChild, onDeleteChild) your use case needs — unneeded buttons won't render
  • Use showChildrenCount={false} to hide the children count badge on node headers
  • Use showSectionBadge={false} to hide the metric badge on section items
  • Use searchQuery with onSearchCountChange to implement a search bar above the tree

API Reference

Props

PropTypeRequiredDefaultDescription
dataScopeTreeNode | null✅—Root node of the tree. Pass null to render nothing.
sectionsConfigTreeSectionConfig[]❌[]Defines section tabs shown under each expanded node.
nodeTypesConfigNodeTypeConfig[]❌[]Defines node labels and add-child behavior per depth level.
defaultExpandedIdsstring[]❌[]Node IDs to expand by default on first render.
searchQuerystring❌''Filters nodes by name. Non-matching subtrees are hidden.
searchSectionsboolean❌falseWhether search query also matches section item labels alongside node names.
onSearchCountChange(count: number) => void❌—Fired when the search result count changes.
onSectionSelect(nodeId: string, sectionId: string) => void❌—Fired when a section tab is clicked. Returns the node ID and section ID.
onAddChild(parentId: string, childType: 'SCOPE' | 'SUBSCOPE', parentName?: string) => void❌—If passed, an Add button appears in the node menu.
onRenameChild(scopeId: string, initialName: string) => void❌—If passed, a Rename button appears in the node menu.
onDeleteChild(scopeId: string, scopeName: string, learningsCount: number) => void❌—If passed, a Delete button appears in the node menu.
selectedRuleSetIdstring | null❌—ID of the node to auto-select on load.
activeSectionIdstring❌—Section ID to auto-activate alongside selectedRuleSetId.
isDraftModeboolean❌falseWhether to display the draft status chip on section items when drafts are available.
enableEllipsisboolean❌falseEnables text truncation with ellipsis for long section labels.
draftChipClassNamestring❌—Custom CSS class name to style the draft chip element.
draftChipDotClassNamestring❌—Custom CSS class name to style the indicator dot inside the draft chip.
draftChipStyleReact.CSSProperties❌—Inline style overrides for the draft chip element.
showChildrenCountboolean❌trueWhether to show the children count badge on parent node headers (including top assistant name node).
showSectionBadgeboolean❌trueWhether to show the metric badge on section items.
showNodeOptionsboolean❌trueWhether to show the 3-dot menu options on node headers.
hideEmptyNodesboolean❌falseIf true, nodes with no children and no sections are hidden.
showEmptyStateboolean❌falseWhether to show an empty state UI when an expanded node has no children/sections.
emptyStateTextstring❌'No data present'Custom text to display in the empty state UI when showEmptyState is true.

TreeSectionConfig

FieldTypeRequiredDescription
idstring✅Unique section identifier.
labelstring✅Display label for the section tab.
iconElementType✅Lucide icon component to show next to the label.
badgeKeykeyof NodeMetrics❌Maps to a key in node.metrics to show as a badge count.
isVisible(node: ScopeTreeNode, depth: number) => boolean❌Optional visibility check per node. If omitted, section is visible for all nodes.

NodeTypeConfig

FieldTypeRequiredDescription
typestring✅Node type identifier (e.g. 'GLOBAL', 'SCOPE', 'SUBSCOPE').
labelstring✅Display label used in delete confirmation text.
addChildLabelstring❌Label for the add child button (e.g. 'Add Scope'). Required if addChildType is set.
addChildTypestring❌The type of child node to create. If omitted, no add button is shown for this node type.

ScopeTreeNode

FieldTypeRequiredDescription
idstring✅Unique identifier for the node.
namestring✅Display name of the node.
type'GLOBAL' | 'SCOPE' | 'SUBSCOPE' | 'Custom'✅Node type.
metricsNodeMetrics✅Metric values used by section badges.
childrenScopeTreeNode[]✅Child nodes. Pass [] for leaf nodes.

Type Definitions

export interface TreeSidebarProps {
  data: ScopeTreeNode | null;
  defaultExpandedIds?: string[];
  onSectionSelect?: (nodeId: string, sectionId: string) => void;
  onNodeOptionsClick?: (nodeId: string) => void;
  onAddChild?: (parentId: string, childType: 'SCOPE' | 'SUBSCOPE', parentName?: string) => void;
  onRenameChild?: (scopeId: string, initialName: string) => void;
  onDeleteChild?: (scopeId: string, scopeName: string, learningsCount: number) => void;
  searchQuery?: string;
  onSearchCountChange?: (count: number) => void;
  sectionsConfig?: TreeSectionConfig[];
  nodeTypesConfig?: NodeTypeConfig[];
  selectedRuleSetId?: string | null;
  activeSectionId?: string;
  showChildrenCount?: boolean;
  showSectionBadge?: boolean;
  isDraftMode?: boolean;
  enableEllipsis?: boolean;
  draftChipClassName?: string;
  draftChipDotClassName?: string;
  draftChipStyle?: React.CSSProperties;
}

export interface TreeSectionConfig {
  id: string;
  label: string;
  icon: any;
  badgeKey?: keyof NodeMetrics;
  isVisible?: (node: ScopeTreeNode, depth: number) => boolean;
}

export interface NodeTypeConfig {
  type: string;
  label: string;
  addChildLabel?: string;
  addChildType?: string;
}

export interface ScopeTreeNode {
  id: string;
  name: string;
  type: 'GLOBAL' | 'SCOPE' | 'SUBSCOPE' | 'Custom';
  metrics: NodeMetrics;
  children: ScopeTreeNode[];
}

export interface NodeMetrics {
  learningsCount: number;
  stationsCount?: number;
}

Examples

const [searchQuery, setSearchQuery] = useState('');
const [searchCount, setSearchCount] = useState(0);

<>
  <input
    value={searchQuery}
    onChange={(e) => setSearchQuery(e.target.value)}
    placeholder="Search scopes..."
  />
  <span>{searchCount} results</span>
  <TreeSidebar
    data={treeData}
    sectionsConfig={sectionsConfig}
    nodeTypesConfig={nodeTypesConfig}
    searchQuery={searchQuery}
    onSearchCountChange={setSearchCount}
  />
</>

With only rename and delete (no add)

<TreeSidebar
  data={treeData}
  sectionsConfig={sectionsConfig}
  nodeTypesConfig={nodeTypesConfig}
  onRenameChild={(scopeId, name) => handleRename(scopeId, name)}
  onDeleteChild={(scopeId, name, count) => handleDelete(scopeId, name, count)}
/>

With badges hidden

<TreeSidebar
  data={treeData}
  sectionsConfig={sectionsConfig}
  nodeTypesConfig={nodeTypesConfig}
  showChildrenCount={false}
  showSectionBadge={false}
/>

With auto-selected node

<TreeSidebar
  data={treeData}
  sectionsConfig={sectionsConfig}
  nodeTypesConfig={nodeTypesConfig}
  selectedRuleSetId="scope-1"
  activeSectionId="learnings"
/>

With multiple sections

import { BookOpen, RadioTower } from 'lucide-react';

<TreeSidebar
  data={treeData}
  sectionsConfig={[
    { id: 'learnings', label: 'Learnings', icon: BookOpen, badgeKey: 'learningsCount' },
    {
      id: 'stations',
      label: 'Stations',
      icon: RadioTower,
      badgeKey: 'stationsCount',
      isVisible: (node, depth) => depth > 0, // Only show for non-root nodes
    },
  ]}
  nodeTypesConfig={nodeTypesConfig}
/>

Notes

  • TreeSidebar is display-only — no internal data fetching. All state and data management lives in the consuming app.
  • Action buttons (Add, Rename, Delete) are conditionally rendered — only shown when the corresponding handler prop is passed.
  • The nodeTypesConfig array maps to tree depth — index 0 applies to the root node, index 1 to its children, and so on. If the tree is deeper than the config array, the last config entry is reused.
  • Delete is automatically disabled for nodes that have children, with a tooltip explaining why.
  • The root node auto-expands on load and whenever data changes.
  • Search expansion is automatic — all ancestor nodes of matching results are expanded.

Assign Reminder & Approval Manager

A configurable modal workflow for assigning users to approval levels, managing due dates and reminders, and tracking review status.

Features

  • Multi-tab interface (Assignees, Reminders, Review Status)
  • Multi-level approval workflows
  • Controlled and uncontrolled state support
  • Async user search and assignment
  • Due date management
  • Final approval workflow support
  • Visual approval progress tracking
  • Customizable metadata, tabs, and priority badges
  • Reusable UI components (Dropdowns, Date Pickers, Checkboxes)

Installation

npm install @e-llm-studio/creative-workspace-ui-component

Public exports

import {
  AssignReminderWrapper,
  AssignReminderLevels,
} from "@e-llm-studio/creative-workspace-ui-component";
  • AssignReminderWrapper provides the complete modal, tabs, validation, reminders, review status, and footer actions.
  • AssignReminderLevels provides the controlled approval-level editor for applications that supply their own surrounding UI.

Internal reminder components, utilities, constants, and AssignReminders types are not currently exported from the package root.

Props

PropTypeDescription
metadataMetaDataCustomizes modal title, priority badge, tabs, and display settings.
reviewDataRecord<number, Record<string, boolean>>Approval status mapping used by Review Status.
levelsLevel[]Approval workflow levels.
setLevelsDispatchControlled state setter for levels.
requireFinalApprovalbooleanEnables final approval step.
finalApprovalStatusbooleanStatus for final approval.
setRequireFinalApprovalDispatchControlled setter for final approval state.
approvalDueDateDate | nullFinal approval due date.
setApprovalDueDateDispatchControlled setter for approval due date.
fetchUsersFetchUsersFunctionAsync user lookup function.
finalApprovalDueDateDate | nullRequired by AssignReminderLevels. Sets the final approval deadline used to constrain level due dates.
onClose() => voidCalled when modal closes.
onSave(payload) => voidReturns configured workflow data.
onValidationError(message) => voidHandles validation errors.

Core Types

MetaData

interface MetaData {
  wrapperTitle?: string;
  wrapperSubTitle?: string;
  wrapperPriority?: string;
  wrapperPriorityStyles?: React.CSSProperties;
  tabData?: TabData[];
  showFinalApprovalDueDate?: boolean;
}

Level

interface Level {
  headerName: string;
  title: string;
  isMandatory: boolean;
  hasDueDate: boolean;
  dueDate: Date | null;
  assignees: AssigneeUser[];
}

AssigneeUser

interface AssigneeUser {
  id: any;
  name: string;
  email: string;
  accessLevel?: string;
}

SavePayload

interface SavePayload {
  levels: Level[];
  requireFinalApproval: boolean;
  finalApprovalDueDate: Date | null;
  activeTab: "assignees" | "reminders" | "review";
}

Included Components

AssignReminderLevels

Manages approval levels, assignees, due dates, and final approval configuration.

ReviewStatus

Displays approval progress and assignee review status using reviewData.

LevelData

Handles assignee search, selection, and access-level assignment.

UI Components

  • CustomDropdown
  • CustomDatePicker
  • AssignLevelDatePicker
  • CustomCheckbox

Basic usage

import { useState } from "react";
import {
  AssignReminderWrapper,
} from "@e-llm-studio/creative-workspace-ui-component";

export function ContractReview() {
  const [open, setOpen] = useState(false);

  const fetchUsers = async (query: string) => {
    const response = await fetch(
      `/api/users?query=${encodeURIComponent(query)}`,
    );
    return response.json();
  };

  return (
    <>
      <button onClick={() => setOpen(true)}>Assign reviewers</button>

      {open && (
        <AssignReminderWrapper
          fetchUsers={fetchUsers}
          requireFinalApproval
          finalApprovalStatus="approved"
          metadata={{
            wrapperTitle: "Contract Review",
            wrapperPriority: "High",
          }}
          onClose={() => setOpen(false)}
          onValidationError={(message) => console.error(message)}
          onSave={(payload) => {
            console.log(payload);
            setOpen(false);
          }}
        />
      )}
    </>
  );
}

fetchUsers is required and must return users containing id, name, and email. The wrapper may be used with its local state or connected to parent state through levels, requireFinalApproval, approvalDueDate, and their setter props.

Key capabilities

  • Debounced asynchronous assignee search
  • Sequential approval levels and access roles
  • Per-level and final approval due-date validation
  • Optional owner final sign-off
  • Dedicated final approval status
  • Manual, scheduled, and escalation reminders
  • Approval and rejection progress tracking
  • Configurable tabs, labels, colors, visibility, and inline style overrides
  • Editing restrictions for read-only or partially locked workflows

On a valid save, onSave receives the normalized visible levels, final approval setting, final due date, active tab, schedules, and reminder owners. The host application remains responsible for persistence and closing the modal.

For the complete props, validation rules, reminder configuration, styling slots, examples, and type reference, see the AssignReminders component guide.

版本与发布记录

@e-llm-studio/creative-workspace-ui-component 共发布 86 个版本,首次发布于 2026/05/21;过去 12 个月发布了 86 个版本。

版本发布日期距今
0.0.69latest2026/10/2816 天前
0.0.682026/10/2123 天前
0.0.672026/10/2123 天前
0.0.662026/10/1628 天前
0.0.652026/10/1628 天前
0.0.642026/10/1529 天前

其他发布通道:beta → 0.0.17-beta.1,alpha → 0.0.45-alpha.1。

关于 @e-llm-studio/creative-workspace-ui-component 的常见问题

@e-llm-studio/creative-workspace-ui-component 是什么?

Reusable React components for Creative Workspace.

如何安装 @e-llm-studio/creative-workspace-ui-component?

在项目目录运行 npm install @e-llm-studio/creative-workspace-ui-component,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:axios(^1.7.9)、dayjs(^1.11.21)、react(^18.3.1)、react-dom(^18.3.1)、primeicons(^7.0.0)、primereact(^10.9.7)、react-icons(^5.3.0)、lucide-react(^0.474.0)、@mui/material(^6.5.0)、framer-motion(^12.42.0)、@emotion/react(^11.14.0)、@emotion/styled(^11.14.1)、@mui/icons-material(^6.5.0)、@mui/x-date-pickers(^7.29.4)、@monaco-editor/react(^4.7.0)、@tanstack/react-query(^5.100.14)、@e-llm-studio/requirement-ai(>=0.0.248)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@e-llm-studio/creative-workspace-ui-component 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@e-llm-studio/creative-workspace-ui-component 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@e-llm-studio/creative-workspace-ui-component 可以商用吗?

@e-llm-studio/creative-workspace-ui-component 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@e-llm-studio/creative-workspace-ui-component 的下载量有多少?

根据 npm 官方下载统计,@e-llm-studio/creative-workspace-ui-component 在 2026/10/13 – 2026/11/11 这 30 天内被下载 2,661 次,日均约 89 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@e-llm-studio/creative-workspace-ui-component 还在维护吗?

最新版本 0.0.69 发布于 2026/10/28(16 天前);至今共发布 86 个版本,其中过去 12 个月发布了 86 个;首次发布于 2026/05/21。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。