插件前端组件与工具文档

本文档只整理 Chatbuddy AI 插件/扩展前端可以直接使用的组件和工具。示例参考
templates/extension-starter/src/web

导入总览

类型导入方式用途
基础 UI 组件@chatbuddy-ai/ui/components/ui/...插件页面、控制台页面的按钮、表单、空状态、状态、时间等
AI 展示组件@chatbuddy-ai/ui/components/ai-elements/...消息、代码块、工具调用、终端、推理过程等展示
展示辅助组件@chatbuddy-ai/ui/components/...复制、文件图标、图标选择、加载、计数动画等
UI hooks@chatbuddy-ai/ui/hooks/...确认弹窗、分页、上传、移动端判断等
页面 hooks@chatbuddy-ai/hooks复制、页面 head、刷新用户/配置等
插件求客户端@chatbuddy-ai/services创建插件前台和控制台 HTTP client
共享上传服务@chatbuddy-ai/services/shared文件上传、OSS 上传、上传配置缓存
状态读取@chatbuddy-ai/stores读取登录用户、站点配置、用户配置
插件路由@chatbuddy-ai/web-core创建插件前台和控制台路由
插件 Vite 配置@chatbuddy-ai/web-core/vite/extension创建插件前端 Vite 配置

插件 Vite 配置

defineExtensionViteConfig

导入:
import { defineExtensionViteConfig } from "@chatbuddy-ai/web-core/vite/extension";
用法:
import { defineExtensionViteConfig } from "@chatbuddy-ai/web-core/vite/extension"; import packageJson from "./package.json"; export default defineExtensionViteConfig(packageJson, { server: { open: true, },
});
可用能力:
能力介绍
React内置 React Vite 插件
Tailwind内置 Tailwind Vite 插件
React Compiler内置 React Compiler preset
路径解析启用tsconfigPaths
插件 base自动配置为/extension/{packageJson.name}
环境变量目录自动配置envDir: ./../../
构建输出默认输出.output/public
chunk 优化lucide-react单独拆为lucidechunk

插件路由

defineRouteOption

导入:
import { defineRouteOption } from "@chatbuddy-ai/web-core";
用法:
import { defineRouteOption } from "@chatbuddy-ai/web-core"; import packageJson from "./../../package.json";
import ArticleDetailPage from "./pages/article/[id]";
import ArticleListPage from "./pages/console/article/list";
import BlogIndexPage from "./pages/index"; export const routeOption = defineRouteOption({ base: `extension/${packageJson.name}`, identifier: packageJson.name, routes: [ { index: true, element: <BlogIndexPage />, }, { path: "article/:id", element: <ArticleDetailPage />, }, ], consoleMenus: [ { title: "文章管理", path: "/", icon: "file-text", }, ], consoleRoutes: [ { index: true, element: <ArticleListPage />, }, ],
});
参数:
参数类型介绍
basestring插件前端 basename,通常为extension/${packageJson.name}
identifierstring插件标识,用于控制台布局获取插件详情
routesRouteObject[]插件前台页面路由
consoleMenusExtensionMenuItem[]插件控制台菜单
consoleRoutesRouteObject[]插件控制台页面路由
内置能力:
能力介绍
控制台布局consoleRoutes自动套ExtensionConsoleLayout
登录守卫控制台路由自动套AuthGuard
全局错误页路由根部接入GlobalError
404 页面未匹配路由渲染插件 404 页面
iframe 路由同步插件路由变化会通过postMessage同步父页面

插件求客户端

createPluginHttpClients

导入:
import { createPluginHttpClients } from "@chatbuddy-ai/services";
用法:
import { createPluginHttpClients } from "@chatbuddy-ai/services"; const { apiHttpClient, consoleHttpClient } = createPluginHttpClients; export { apiHttpClient, consoleHttpClient };
客户端:
客户端用途对应后端
apiHttpClient插件前台接口ExtensionWebController
consoleHttpClient插件控制台接口ExtensionConsoleController
React Query 示例:
import type { MutationOptionsUtil, PaginatedQueryOptionsUtil, PaginatedResponse, QueryOptionsUtil,
} from "@chatbuddy-ai/web-types";
import { useMutation, useQuery } from "@tanstack/react-query"; import { consoleHttpClient } from "../base";
import type { Article, CreateArticleParams, QueryArticleParams } from "../types/article"; export function useArticleListQuery( params?: QueryArticleParams, options?: PaginatedQueryOptionsUtil<Article>,
) { return useQuery({ queryKey: ["articles", "list", params], queryFn: => consoleHttpClient.get<PaginatedResponse<Article>>("/article", { params }), ...options, });
} export function useArticleDetailQuery(id: string, options?: QueryOptionsUtil<Article>) { return useQuery<Article>({ queryKey: ["articles", "detail", id], queryFn: => consoleHttpClient.get<Article>(`/article/${id}`), enabled: !!id && options?.enabled !== false, ...options, });
} export function useCreateArticleMutation( options?: MutationOptionsUtil<Partial<Article>, CreateArticleParams>,
) { return useMutation<Partial<Article>, Error, CreateArticleParams>({ mutationFn: (data) => consoleHttpClient.post<Partial<Article>>("/article", data), ...options, });
}

基础 UI 组件

Button

导入:
import { Button } from "@chatbuddy-ai/ui/components/ui/button";
可用 props:
prop介绍
variantdefaultoutlinesecondaryghostdestructivelink
sizedefaultxssmlgiconicon-xsicon-smicon-lg
loading加载态,自动禁用按钮并显示 spinner
asChild将按钮样式传给子元素
<Button type="submit" variant="outline" size="sm" loading={isSubmitting}> 提交
</Button>

Spinner

导入:
import { Spinner } from "@chatbuddy-ai/ui/components/ui/spinner";
<Spinner className="size-4" />

Empty

导入:
import { Empty, EmptyContent, EmptyDescription, EmptyMedia, EmptyTitle,
} from "@chatbuddy-ai/ui/components/ui/empty";
<Empty> <EmptyMedia variant="icon"> <Search className="size-5" /> </EmptyMedia> <EmptyContent> <EmptyTitle>暂无文章</EmptyTitle> <EmptyDescription>创建第一篇文章后会显示在这里。</EmptyDescription> </EmptyContent>
</Empty>

Field

导入:
import { Field, FieldContent, FieldDescription, FieldGroup, FieldLabel, FieldSet,
} from "@chatbuddy-ai/ui/components/ui/field";
<FieldSet> <FieldGroup> <Field> <FieldLabel>标题</FieldLabel> <FieldContent> <Input value={title} onChange={(event) => setTitle(event.target.value)} /> <FieldDescription>最多 200 个字符。</FieldDescription> </FieldContent> </Field> </FieldGroup>
</FieldSet>

StatusBadge

导入:
import { StatusBadge } from "@chatbuddy-ai/ui/components/ui/status-badge";
可用 props:
prop介绍
active是否为启用态
activeText启用态文案
inactiveText停用态文案
activeVariant启用态 badge 样式
inactiveVariant停用态 badge 样式
<StatusBadge active={article.status === "published"} activeText="已发布" inactiveText="草稿" />

TimeText

导入:
import { TimeText } from "@chatbuddy-ai/ui/components/ui/time-text";
可用 props:
prop介绍
valueDate、字符串或时间戳
variantdatetimedatetimerelative
format自定义格式
fallback空值展示
<TimeText value={article.createdAt} variant="datetime" />
<TimeText value={article.updatedAt} variant="relative" />

InputGroup

导入:
import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText,
} from "@chatbuddy-ai/ui/components/ui/input-group";
<InputGroup> <InputGroupAddon> <Search className="size-4" /> </InputGroupAddon> <InputGroupInput placeholder="搜索文章" /> <InputGroupButton size="sm">搜索</InputGroupButton>
</InputGroup>

Combobox

导入:
import { Combobox, ComboboxContent, ComboboxInput, ComboboxItem, ComboboxTrigger,
} from "@chatbuddy-ai/ui/components/ui/combobox";
适用于插件里的分类选择、标签选择、模型选择等搜索选择场景。

DataTableFacetedFilter

导入:
import { DataTableFacetedFilter } from "@chatbuddy-ai/ui/components/ui/data-table-faceted-filter";
<DataTableFacetedFilter title="状态" selectedValue={status} onSelectionChange={setStatus} options={[ { label: "已发布", value: "published" }, { label: "草稿", value: "draft" }, ]}
/>

上传组件和工具

ImageUpload

导入:
import { ImageUpload } from "@chatbuddy-ai/ui/components/ui/image-upload";
可用 props:
prop介绍
value当前图片 URL
defaultValue默认图片 URL
accept文件类型
maxSize最大大小
placeholder占位内容
onChange上传完成后回调
onUploadStart上传开始回调
onUploadError上传失败回调
sizesmdefaultlgxl
shapecirclerounded
<ImageUpload value={cover} accept="image/*" maxSize={5 * 1024 * 1024} onChange={(url) => setCover(url)}
/>

Upload 和 useUpload

导入:
import { Upload, useUpload } from "@chatbuddy-ai/ui/components/upload";
可用能力:
能力介绍
multiple多文件上传
accept限制文件类型
maxSize限制单文件大小
maxFiles限制文件数量
params透传上传参数
onUploadProgress上传进度
onUploadSuccess单文件成功
onUploadError上传失败
onUploadComplete批量完成

useUploadFile

导入:
import { useUploadFile } from "@chatbuddy-ai/ui/hooks/use-upload-file";
返回值:
字段介绍
isUploading是否上传中
progress上传进度
uploadedFile上传完成文件
uploadFile执行上传
uploadingFile当前上传文件

共享上传服务

导入:
import { detectFileType, invalidateStorageConfigCache, uploadFile, uploadFileAuto, uploadFiles, uploadFilesAuto, uploadInitFile,
} from "@chatbuddy-ai/services/shared";
可用工具:
工具介绍
uploadFile上传单文件
uploadFiles上传多文件
uploadInitFile系统初始化阶段上传文件
uploadFileAuto自动选择上传方式上传单文件
uploadFilesAuto自动选择上传方式上传多文件
detectFileType识别文件类型
invalidateStorageConfigCache清理上传配置缓存

AI 展示组件

Message

导入:
import { Message, MessageContent } from "@chatbuddy-ai/ui/components/ai-elements/message";
<Message from="assistant"> <MessageContent>生成完成。</MessageContent>
</Message>

CodeBlock

导入:
import { CodeBlock, CodeBlockCopyButton, CodeBlockHeader, CodeBlockTitle,
} from "@chatbuddy-ai/ui/components/ai-elements/code-block";
<CodeBlock code={source} language="tsx" showLineNumbers> <CodeBlockHeader> <CodeBlockTitle>example.tsx</CodeBlockTitle> <CodeBlockCopyButton /> </CodeBlockHeader>
</CodeBlock>

Tool

导入:
import { Tool, ToolContent, ToolHeader, ToolOutput,
} from "@chatbuddy-ai/ui/components/ai-elements/tool";
<Tool> <ToolHeader type="tool-call" state="output-available" /> <ToolContent> <ToolOutput output="执行完成" /> </ToolContent>
</Tool>

其他 AI 展示组件

组件路径可用组件
ai-elements/conversation对话容器
ai-elements/prompt-input提示词输入框
ai-elements/reasoning推理过程
ai-elements/terminal终端输出
ai-elements/sources来源引用
ai-elements/file-tree文件树
ai-elements/task任务状态
ai-elements/tests测试结果
ai-elements/stack-trace错误堆栈
ai-elements/preview预览内容

展示辅助组件

CopyButton

导入:
import { CopyButton } from "@chatbuddy-ai/ui/components/copy-button";
<CopyButton value={article.url} size="icon-sm" />

FileFormatIcon

导入:
import { FileFormatIcon } from "@chatbuddy-ai/ui/components/file-format-icon";
<FileFormatIcon filename={file.name} />

LucideIcon

导入:
import { LucideIcon } from "@chatbuddy-ai/ui/components/lucide-icon";
<LucideIcon name="file-text" className="size-4" />

IconPicker

导入:
import { IconPicker } from "@chatbuddy-ai/ui/components/icon-picker";
可用 props:
prop介绍
value当前图标名
onChange选择变化回调
placeholder占位文案
disabled禁用
containerPopover 容器
<IconPicker value={icon} onChange={setIcon} placeholder="选择菜单图标" />

Loader、ReloadWindow、CountUp、SplitText

导入:
import Loader from "@chatbuddy-ai/ui/components/loader";
import ReloadWindow from "@chatbuddy-ai/ui/components/reload-window";
import { CountUp } from "@chatbuddy-ai/ui/components/count-up";
import { SplitText } from "@chatbuddy-ai/ui/components/split-text";
组件场景
Loader页面或局部加载
ReloadWindow提示刷新页面
CountUp数字动画
SplitText文本拆分动画

常用 hooks

useAlertDialog

导入:
import { useAlertDialog } from "@chatbuddy-ai/ui/hooks/use-alert-dialog";
const { confirm } = useAlertDialog; await confirm({ title: "移除文章", description: "移除后不可恢复,确认继续?",
});

usePagination

导入:
import { usePagination } from "@chatbuddy-ai/ui/hooks/use-pagination";
返回值:
字段介绍
currentPage当前页
totalPages总页数
pageSize每页数量
total总条数
hasPrevious是否有上一页
hasNext是否有下一页
goToPage跳转页码
nextPage下一页
previousPage上一页
reset重置分页
PaginationComponent分页组件

useCopy

导入:
import { useCopy } from "@chatbuddy-ai/hooks";
const { copy, isCopying } = useCopy; await copy(article.url);

useDocumentHead

导入:
import { useDocumentHead } from "@chatbuddy-ai/hooks";
useDocumentHead({ title: "文章管理",
});

其他可用 hooks

hook导入场景
useMobile@chatbuddy-ai/ui/hooks/use-mobile判断移动端
useMounted@chatbuddy-ai/ui/hooks/use-mounted判断组件是否已挂载
useDebounce@chatbuddy-ai/ui/hooks/use-debounce输入防抖
useRefreshUser@chatbuddy-ai/hooks刷新当前用户
useRefreshUserConfig@chatbuddy-ai/hooks刷新用户配置
useRefreshWebsiteConfig@chatbuddy-ai/hooks刷新站点配置

状态读取

导入:
import { useAuthStore, useConfigStore, useUserConfigStore } from "@chatbuddy-ai/stores";
可用 store:
store介绍
useAuthStore当前登录状态、用户信息、权限码
useConfigStore站点配置
useUserConfigStore用户配置
示例:
const userInfo = useAuthStore((state) => state.auth.userInfo);
const websiteConfig = useConfigStore((state) => state.config);

类型工具

导入:
import type { MutationOptionsUtil, PaginatedQueryOptionsUtil, PaginatedResponse, QueryOptionsUtil,
} from "@chatbuddy-ai/web-types";
可用类型:
类型介绍
PaginatedResponse<T>分页响应
QueryOptionsUtil<T>React Query 查询 options
PaginatedQueryOptionsUtil<T>分页查询 options
MutationOptionsUtil<TData, TVariables>mutation options

319 篇文档 · 内容同步自官方帮助中心