hyosan-chat v0.2.0
hyosan-chat

介绍
hyosan-chat 是一个基于 Lit 和 Shoelace 实现的 AI 对话组件库; 该项目旨在提供一个现代化、高性能且易于扩展的 Web 组件库, 用于构建智能对话界面; 最终实现效果将类似于 ant-design-x
功能特性
Web Components: 使用 Lit 构建的自定义元素, 确保跨框架兼容性UI组件库: 基于成熟的基础组件库 ShoelaceAI集成: 支持与多种AI模型和服务集成, 提供智能对话功能- 模块化设计: 组件高度解耦, 便于按需引入和扩展
- 性能优化: 通过 vite@^6.1.0 构建工具链, 确保快速开发和高效的生产环境性能
技术栈
- Lit@^3.2.1:
Web Component库 - shoelace@^2.20.0: 使用
Web Components实现的UI组件库 - vite@^6.1.0: 现代化的前端构建工具
- TypeScript: 强类型语言, 确保代码质量和可维护性
- biome:代码格式化和
lint工具, 保证代码风格一致性和质量
安装
pnpm i git+https://github.com/SublimeCT/hyosan-chat.git#main使用
🔗 demo 页面 的源码可直接参考 src/hyosan-chat-demo.ts
组件附带了一个用于声明自定义元素信息的文件, 可以实现在 vscode / JetBrains IDE 中的代码补全功能
vscode
需要在 vscode 的 settings.json 中声明组件提供的 types:
.vscode/settings.json:
{
+ "html.customData": [
+ "./node_modules/hyosan-chat/dist/cem-types/vscode.html-custom-data.json"
+ ]
}JetBrains IDE
组件已经声明了一个 dist/web-types.json 文件, 在 JetBrains IDE 中应该会检测到, 如果没有任何提示, 你可能需要在 package.json 中声明 web-types, 可参考 JetBrains IDEs - Shoelace
TypeScript
组件完全使用 TypeScript 编写, 也基于 custom-elements-manifest 提供了一流的 TypeScript 支持, 只需引入组件提供的类型文件即可
tsconfig.json:
{
"compilerOptions": {
// ...
+ "types": [
+ "hyosan-chat/dist/cem-types/vue/index.d.ts"
+ ]
},
}vue
!TIP 请先阅读官方文档 在 Vue 中使用自定义元素
在 Vue 中默认将所有元素作为 vue 组件, 但自定义元素不能被当做 vue 组件进行处理, 我们需要显示地声明哪些是自定义组件:
vite.config.ts:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vite.dev/config/
export default defineConfig({
plugins: [
vue({
template: {
compilerOptions: {
isCustomElement: tag => tag.includes('hyosan-')
}
}
})
],
})以上配置是将 hyosan-* 组件作为自定义组件处理
- 在代码中我们也必须严格使用
<hyosan-chat>, 而不能写成<HyosanChat> - 对于
slot也不能使用v-slot/#语法, 因为Web Components的插槽是原生的 slot, vue 的特殊插槽语法无法在自定义组件中使用
vue 对于 Property 参数(在 Properties 中标注了哪些属性是 Property) 必须添加 .prop 修饰符:
<hyosan-chat :messages.prop="messages"></hyosan-chat>react
TODO
API
Properties
关于 属性类型:
Lit@^3.2.1 组件可以接收
Property/Attribute参数:
Attribute: 通过HTML元素的属性(attribute) 传递数据, 并且attribute属性值会转换为string类型Property: 通过JS获取组件, 并 在组件对象上 添加属性, 并且Property属性值会转换为JS原生数据类型
| 属性名 | 类型 | 属性类型 | 默认值 | 描述 | Reflect |
|---|---|---|---|---|---|
applicationTitle | string | Attribute | 'Hyosan Chat' | 应用标题 | |
panelSnap | string | Attribute | '25% 50%' | 分割面板的可捕捉位置 | ✅ |
panelPosition | number | Attribute | 25 | 分隔线与主面板边缘的当前位置(百分比, 0-100), 默认为容器初始大小的 50% | ✅ |
💡 conversations | Array<Conversation> | Property | [] | 会话列表数据源 | ✅ |
currentConversationId | BaseService | Attribute | '' | 当前会话 ID | ✅ |
💡 service | BaseService | Property | new DefaultService() | 会话服务配置参数 | |
💡 messages | BaseServiceMessages | Property | undefined | 会话服务消息列表 | ✅ |
showAvatar | boolean | Attribute | undefined | 是否显示头像 | ✅ |
showRetryButton | boolean | Attribute | true | 是否显示 重新生成 按钮 | |
showLikeAndDislikeButton | boolean | Attribute | true | 是否显示 👍 和 👎 按钮 | |
onCreateMessage | (content?: string) => string \| Promise<string> | Property | 创建消息的回调函数, 当 没有选中会话 或 点击开始新聊天按钮 时, 如果直接开始发送消息, 会调用此函数, 组件会等待函数返回一个 conversationId, 然后再发送消息; 如果不返回 conversationId, 则不会在组件内部改变 conversationId, 这就相当于创建了一个没有回话 ID 的临时聊天 | ||
onEnableSearch | (open: boolean) => void \| Promise<void> | Property | 如果传入则显示联网搜索按钮, 用户点击搜索按钮时 调用此方法 | ||
shoelaceTheme | HyosanChatShoelaceTheme | Attribute | shoelace 主题, 可用于切换夜间模式 |
Slots
!TIP 关于 插槽 Lit@^3.2.1 的插槽与
vue的插槽不同, 基于原生的<slot>元素 实现, 不具备作用域插槽, 也不能在组件内部多次渲染插槽
| 名称 | 描述 |
|---|---|
conversations | 左侧会话列表 |
conversations-header | 左侧会话列表的 header 部分 |
conversations-footer | 左侧会话列表的 footer 部分 |
main-welcome | 右侧消息列表的 welcome 界面 |
main-header | 右侧消息列表的 header 部分 |
Events
| 事件名 | 参数 | 描述 |
|---|---|---|
conversations-create | undefined | 点击创建新会话按钮 |
click-conversation | CustomEvent<{ item: Conversation }> | 点击左侧会话列表中的会话 |
change-conversation | CustomEvent<{ item: Conversation }> | 点击 切换 左侧会话列表中的会话 |
send-message | CustomEvent<{ content: string }> | 点击发送按钮 |
hyosan-chat-settings-save | CustomEvent<{ settings: ChatSettings }> | 在设置弹窗中点击保存按钮 |
edit-conversation | CustomEvent<{ item: Converastion }> | 在会话列表中点击编辑按钮, 并保存 |
delete-conversation | CustomEvent<{ item: Converastion }> | 在会话列表中点击删除按钮 |
hyosan-chat-click-like-button | CustomEvent<{ message: BaseServiceMessageItem, item: BaseServiceMessageNode }> | 点击 Like 按钮(点赞) |
hyosan-chat-click-dislike-button | CustomEvent<{ message: BaseServiceMessageItem, item: BaseServiceMessageNode }> | 点击 Dislike 按钮(点踩) |
CSS Parts
可以使用 ::part() 选择器修改组件的样式, 由于 Web Components 的样式隔离的特性, 组件外部想要修改组件内的样式只能通过 ::part() 选择器或组件内部引用的 css 变量 来进行控制
| 名称 | 描述 |
|---|---|
base | 根组件(hyosan-chat) 最外层元素 |
CSS Variables
组件提供的 css 变量包含两部分:
- 基础组件库 shoelace 的 css 变量: 参考 Themes - shoelace
- 组件内部使用的 css 变量: 参考 src/sheets/global-styles.css 文件
主题
组件通过底层的基础组件库 shoelace 提供了基础的 light / dark 两种主题, 如需创建新主题, 可参考 Creating a theme
贡献指南
参考 CONTRIBUTING