unnamed-ui
折叠/步骤

Thinking Step Item

Sub-step item component for displaying nested steps inside thinking process content

明确研究目标与边界
明确研究目标与边界,我将调用知识和搜索工具
调取知识:
我正在调取知识库资料
📄
AI发展趋势.pdf
📄
AI发展历史.doc
明确研究目标与边界,我将调用知识和搜索工具
调取知识:
我正在调取知识库资料
📄
AI发展趋势.pdf
📄
AI发展历史.doc
明确研究目标与边界,我将调用知识和搜索工具
调取知识:
我正在调取知识库资料
📄
AI发展趋势.pdf
📄
AI发展历史.doc
已取消
正在解析简历信息
思考中...
解析中:
正在处理附件与字段映射
调取知识库
调取知识:
已从知识库中检索到 5 条相关岗位要求信息
API 调用失败
无法连接到外部 API 服务,请检查网络连接后重试。
"use client";

import { BookOpen } from "lucide-react";
import { ThinkingStepItem } from "@/components/composed/thinking-step-item/thinking-step-item";

export function ThinkingStepItemDemo() {
  return (
    <div className="w-full max-w-2xl space-y-4 h-full">
      {/* 默认:不启用折叠(内容直接展示,无箭头) */}
      <ThinkingStepItem
        status="success"
        title="明确研究目标与边界"
        statusIcon={<BookOpen className="size-4" />}
        items={[
          {
            content: "明确研究目标与边界,我将调用知识和搜索工具",
            toolCall: {
              icon: <BookOpen className="size-4" />,
              title: "调取知识",
              content: "我正在调取知识库资料",
            },
            files: [
              { icon: "📄", name: "AI发展趋势.pdf" },
              { icon: "📄", name: "AI发展历史.doc" },
            ],
          },
          {
            content: "明确研究目标与边界,我将调用知识和搜索工具",
            toolCall: {
              icon: <BookOpen className="size-4" />,
              title: "调取知识",
              content: "我正在调取知识库资料",
            },
            files: [
              { icon: "📄", name: "AI发展趋势.pdf" },
              { icon: "📄", name: "AI发展历史.doc" },
            ],
          },
          {
            content: "明确研究目标与边界,我将调用知识和搜索工具",
            toolCall: {
              icon: <BookOpen className="size-4" />,
              title: "调取知识",
              content: "我正在调取知识库资料",
            },
            files: [
              { icon: "📄", name: "AI发展趋势.pdf" },
              { icon: "📄", name: "AI发展历史.doc" },
            ],
          },
        ]}
      />

      {/* 可选:启用折叠(展示箭头,支持展开/收起) */}
      <ThinkingStepItem
        collapsible
        status="success"
        title="(可折叠)查看详情"
        items={[
          {
            key: "collapsible",
            content: "当你传入 collapsible 时才会启用展开/收起交互。",
          },
        ]}
        defaultOpen={false}
      />

      {/* 取消状态(默认不折叠) */}
      <ThinkingStepItem status="cancel" title="已取消" items={[]} />

      {/* 加载中状态 */}
      <ThinkingStepItem
        status="loading"
        title="正在解析简历信息"
        items={[
          {
            // 不传 content:将自动显示“思考中...”并闪烁
            toolCall: {
              icon: <BookOpen className="size-4" />,
              title: "解析中",
              content: "正在处理附件与字段映射",
            },
          },
        ]}
      />

      {/* 成功状态 - 带工具调用 */}
      <ThinkingStepItem
        status="success"
        title="调取知识库"
        items={[
          {
            toolCall: {
              icon: <BookOpen className="size-4" />,
              title: "调取知识",
              content: "已从知识库中检索到 5 条相关岗位要求信息",
            },
          },
        ]}
      />

      {/* 错误状态 */}
      <ThinkingStepItem
        status="error"
        title="API 调用失败"
        items={[
          {
            content: "无法连接到外部 API 服务,请检查网络连接后重试。",
          },
        ]}
      />
    </div>
  );
}

Thinking Step Item 组件用于在思考过程内容中展示子步骤:状态、(可选)折叠详情、工具调用信息与文件附件。

概述

  • 适用场景:思考过程拆分、任务流水线、工具调用轨迹、文件处理进度。
  • 两层用法
    • 业务组件 ThinkingStepItem:开箱即用(推荐)。
    • Primitives:在不改内部实现的前提下自定义布局/内容(高级用法)。

快速开始

import { ThinkingStepItem } from "@/registry/wuhan/composed/thinking-step-item/thinking-step-item";

export function Example() {
  return (
    <ThinkingStepItem
      status="success"
      title="解析简历信息"
      items={[{ content: "成功提取了候选人的基本信息、工作经历、教育背景和技能列表。" }]}
    />
  );
}

特性

  • 四种状态:loading(加载中)、success(成功)、error(错误)、cancel(取消)
  • 状态图标:每种状态有专属的图标和颜色
  • 可选折叠:默认不折叠;需要时可通过 collapsible 启用展开/收起
  • 原语化设计:提供完整的原语组件,高度可定制
  • 灵活内容:支持文本、工具调用信息、文件附件等组合
  • Hover 高亮:鼠标悬停时标题和箭头变为品牌色
  • 样式隔离:组件样式不受外部框架影响

安装

pnpm dlx shadcn@latest add http://localhost:3000/r/wuhan/thinking-step-item.json

代码演示

默认状态

基础用法,展示成功状态的子步骤。

解析简历信息
成功提取了候选人的基本信息、工作经历、教育背景和技能列表。
"use client";

import * as React from "react";
import { ThinkingStepItem } from "@/components/composed/thinking-step-item/thinking-step-item";

export function ThinkingStepItemDefault() {
  return (
    <div className="w-full max-w-2xl">
      {/* 默认用法 - 成功状态 */}
      <ThinkingStepItem
        status="success"
        title="解析简历信息"
        items={[
          {
            content:
              "成功提取了候选人的基本信息、工作经历、教育背景和技能列表。",
          },
        ]}
        defaultOpen
      />
    </div>
  );
}

包含附件

子步骤包含文件附件的展示。

处理附件文件
已成功解析以下文件:
📄
resume.pdf
📄
cover-letter.docx
📊
portfolio.xlsx
🖼️
certificate.jpg
📄
reference-letter.pdf
"use client";

import * as React from "react";
import { ThinkingStepItem } from "@/components/composed/thinking-step-item/thinking-step-item";

export function ThinkingStepItemWithAttachments() {
  return (
    <div className="w-full max-w-2xl">
      {/* 带文件附件的子步骤 */}
      <ThinkingStepItem
        status="success"
        title="处理附件文件"
        items={[
          {
            content: "已成功解析以下文件:",
            files: [
              { icon: "📄", name: "resume.pdf" },
              { icon: "📄", name: "cover-letter.docx" },
              { icon: "📊", name: "portfolio.xlsx" },
              { icon: "🖼️", name: "certificate.jpg" },
              { icon: "📄", name: "reference-letter.pdf" },
            ],
          },
        ]}
        defaultOpen
      />
    </div>
  );
}

文件列表溢出

文件列表超出两排时,会出现“查看更多”,并且按钮与文件项处于同一行流式布局。

处理附件文件(超出两排)
文件较多,默认只展示两排,超过两排会出现“查看更多”。
📄
resume.pdf
📄
cover-letter.docx
📊
portfolio.xlsx
🖼️
certificate.jpg
📄
reference-letter.pdf
uploading-attachments.zip
"use client";

import { ThinkingStepItem } from "@/components/composed/thinking-step-item/thinking-step-item";

export function ThinkingStepItemWithOverflowFiles() {
  return (
    // 使用较窄的宽度,确保文件项会换行,触发“超过两排显示更多”的行为
    <div className="w-full max-w-md">
      <ThinkingStepItem
        status="success"
        title="处理附件文件(超出两排)"
        items={[
          {
            key: "overflow-files",
            content: "文件较多,默认只展示两排,超过两排会出现“查看更多”。",
            files: [
              { icon: "📄", name: "resume.pdf" },
              { icon: "📄", name: "cover-letter.docx" },
              { icon: "📊", name: "portfolio.xlsx" },
              { icon: "🖼️", name: "certificate.jpg" },
              { icon: "📄", name: "reference-letter.pdf" },
              { status: "loading", name: "uploading-attachments.zip" },
              { icon: "🧾", name: "invoice-2025-12.pdf" },
              { icon: "📎", name: "attachments.zip" },
              { icon: "📄", name: "work-history.pdf" },
              { icon: "📄", name: "education.docx" },
              { icon: "📄", name: "skills.txt" },
              { icon: "📄", name: "awards.pdf" },
              { icon: "📄", name: "projects.md" },
              { icon: "📄", name: "notes.txt" },
              { icon: "📄", name: "more-files.pdf" },
            ],
          },
        ]}
        defaultOpen
      />
    </div>
  );
}

包含标签

子步骤包含标签列表的展示。

调取知识库
知识库查询:
已从知识库中检索到 5 条相关岗位要求信息
多步骤执行
搜索引擎:
搜索了相关技术栈和行业趋势
数据库查询:
查询了候选人历史记录
文档分析:
分析了简历和岗位描述
"use client";

import * as React from "react";
import { ThinkingStepItem } from "@/components/composed/thinking-step-item/thinking-step-item";
import { Database, Search, FileText } from "lucide-react";

export function ThinkingStepItemWithTags() {
  return (
    <div className="w-full max-w-2xl space-y-4">
      {/* 带工具调用的子步骤 */}
      <ThinkingStepItem
        status="success"
        title="调取知识库"
        items={[
          {
            toolCall: {
              icon: <Database className="size-4" />,
              title: "知识库查询",
              content: "已从知识库中检索到 5 条相关岗位要求信息",
            },
          },
        ]}
        defaultOpen
      />

      {/* 带多个工具调用的子步骤 */}
      <ThinkingStepItem
        status="success"
        title="多步骤执行"
        items={[
          {
            toolCall: {
              icon: <Search className="size-4" />,
              title: "搜索引擎",
              content: "搜索了相关技术栈和行业趋势",
            },
          },
          {
            toolCall: {
              icon: <Database className="size-4" />,
              title: "数据库查询",
              content: "查询了候选人历史记录",
            },
          },
          {
            toolCall: {
              icon: <FileText className="size-4" />,
              title: "文档分析",
              content: "分析了简历和岗位描述",
            },
          },
        ]}
        defaultOpen
      />
    </div>
  );
}

Behavior Spec

折叠/展开(受控 vs 非受控)

  • 默认 不启用折叠:不显示箭头、Header 不可点击、内容(若有)直接展示
  • 启用折叠:传 collapsible
    • 非受控:使用 defaultOpen
    • 受控:传 open + onOpenChange
    • 同时传入时:由 open(受控)决定展示状态

文件列表(两排 + 更多同排)

items[].files 存在时,会渲染文件列表,折叠态行为约定如下:

  • 默认折叠态最多两排(按实际布局换行判断,而不是按数量)
  • 超过两排才出现“查看更多”
  • “查看更多/收起”按钮与文件项处于同一行流式布局(flex-wrap 同容器)
  • 展开后展示全部文件项;按钮文案切换为“收起”

Loading 占位文案

status="loading" 且某个 items[] 没有提供 content 时,会自动使用 ThinkingStepItemRegularContentPrimitive 显示 “思考中...”,并带有 animate-pulse 闪烁效果。

Usage

基本

import { ThinkingStepItem } from "@/registry/wuhan/composed/thinking-step-item/thinking-step-item";

<ThinkingStepItem
  status="success"
  title="解析简历信息"
  items={[
    {
      content: "成功提取了候选人的基本信息、工作经历、教育背景和技能列表。",
    },
  ]}
  defaultOpen
/>

多个子步骤

import { ThinkingStepItem } from "@/registry/wuhan/composed/thinking-step-item/thinking-step-item";
import { ThinkingStepItemContainerPrimitive } from "@/registry/wuhan/blocks/thinking-step-item/thinking-step-item-01";

<ThinkingStepItemContainerPrimitive>
  <ThinkingStepItem
    status="success"
    title="步骤 1"
    items={[{ key: "step-1", content: "已完成" }]}
  />
  <ThinkingStepItem
    status="loading"
    title="步骤 2"
    items={[{ key: "step-2", content: "正在处理..." }]}
  />
  <ThinkingStepItem
    status="cancel"
    title="步骤 3"
    items={[]}
  />
</ThinkingStepItemContainerPrimitive>

带工具调用

import { ThinkingStepItem } from "@/registry/wuhan/composed/thinking-step-item/thinking-step-item";
import { Database } from "lucide-react";

<ThinkingStepItem
  status="success"
  title="调取知识库"
  items={[
    {
      toolCall: {
        icon: <Database className="size-4" />,
        title: "知识库查询",
        content: "已从知识库中检索到 5 条相关岗位要求信息",
      },
    },
  ]}
  defaultOpen
/>

带文件列表

import { ThinkingStepItem } from "@/registry/wuhan/composed/thinking-step-item/thinking-step-item";

<ThinkingStepItem
  status="success"
  title="处理附件文件"
  items={[
    {
      key: "attachments",
      content: "已成功解析以下文件:",
      files: [
        { icon: "📄", name: "resume.pdf" },
        { icon: "📄", name: "cover-letter.docx" },
        { icon: "📊", name: "portfolio.xlsx" },
      ],
    },
  ]}
  defaultOpen
/>

状态说明

状态图标颜色典型使用
loading旋转圈蓝色(品牌色)正在执行的子步骤
success勾选绿色(成功色)已完成的子步骤
error感叹号红色(错误色)执行失败的子步骤
cancel空圆圈灰色已取消的子步骤

API

ThinkingStepItem

高级业务组件,封装了常用功能。

属性类型默认值说明
status'loading' | 'success' | 'error' | 'cancel''loading'步骤状态
titleReact.ReactNode-步骤标题(必填)
collapsiblebooleanfalse是否启用折叠/展开交互
itemsArray<{ key?: React.Key; content?: React.ReactNode; toolCall?: { icon?: React.ReactNode; title?: React.ReactNode; content?: React.ReactNode; }; files?: Array<{ icon?: React.ReactNode; status?: 'loading' | 'ready' | 'error'; name: string; }>; }>[]步骤内容项列表(推荐为每项提供 key
statusIconReact.ReactNode-自定义状态图标(优先级高于内置状态图标)
arrowIconReact.ReactNode-自定义折叠箭头图标
defaultOpenbooleanfalse是否默认展开
openboolean-控制展开状态(受控)
onOpenChange(open: boolean) => void-展开状态变化回调

Primitives(原语组件)

ThinkingStepItemContainerPrimitive

容器组件,包裹多个步骤,提供统一间距。

ThinkingStepItemPrimitive

单个步骤的容器原语,支持 Collapsible 功能。

ThinkingStepItemHeaderPrimitive

步骤头部原语,可点击展开/收起。

ThinkingStepItemContentPrimitive

步骤内容区域原语,带左侧缩进。

ThinkingStepItemTitlePrimitive

标题文本原语,hover 时变为品牌色。

ThinkingStepItemStatusIconPrimitive

状态图标容器原语,根据状态显示不同颜色。

ThinkingStepItemCollapseArrowPrimitive

折叠箭头原语,展开时旋转 180 度。

ThinkingStepItemContentListPrimitive

内容列表原语,用于展示多个内容项。

ThinkingStepItemContentItemPrimitive

内容项原语,单个内容项的容器。

ThinkingStepItemTimelinePrimitive

时间轴原语,显示左侧的时间轴装饰。

ThinkingStepItemContentAreaPrimitive

内容区域原语,包裹实际内容。

ThinkingStepItemRegularContentPrimitive

普通内容原语,用于显示文本内容。

ThinkingStepItemToolCallPrimitive

工具调用原语,用于显示工具调用信息(图标、标题、内容)。

ThinkingStepItemFileListPrimitive

文件列表原语,用于显示文件列表。

ThinkingStepItemFileItemPrimitive

文件项原语,单个文件的展示。

Design Tokens

组件只消费全局 token(如 --text-* / --bg-* / --gap-* / --radius-*),不输出全局样式。主题接入时可通过覆盖 token 完成换肤。

使用场景

  • 在 Thinking Process 中使用:在主思考块的 content 中展示多个子步骤
  • 工具调用展示:展示调用知识库、搜索引擎等工具的过程
  • 文件处理流程:展示文件上传、解析、处理的各个子步骤
  • API 请求链:展示多个 API 调用的执行状态
  • 数据处理管道:展示数据清洗、转换、分析等子阶段

与 Thinking Process 组合使用

import { ThinkingStep } from "@/registry/wuhan/composed/thinking-process/thinking-process";
import { ThinkingStepItem } from "@/registry/wuhan/composed/thinking-step-item/thinking-step-item";
import { ThinkingStepItemContainerPrimitive } from "@/registry/wuhan/blocks/thinking-step-item/thinking-step-item-01";

<ThinkingStep
  status="completed"
  title="分析完成"
  duration={30}
  content={
    <ThinkingStepItemContainerPrimitive>
      <ThinkingStepItem
        status="success"
        title="解析简历"
        items={[{ content: "已完成" }]}
      />
      <ThinkingStepItem
        status="success"
        title="分析匹配度"
        items={[{ content: "匹配度: 85%" }]}
      />
      <ThinkingStepItem
        status="success"
        title="生成问题"
        items={[{ content: "已生成 10 个问题" }]}
      />
    </ThinkingStepItemContainerPrimitive>
  }
/>

Changelog

  • files.icon:支持从 string 扩展为 React.ReactNode
  • statusIcon:支持覆盖内置状态图标
  • 文件列表折叠逻辑:以“最多两排 + 更多同排”为契约(按实际布局判断)