Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
{
"component": true,
"styleIsolation": "apply-shared",
"componentGenerics": {
"tail-component": {
"default": "tdesign-miniprogram/chat-markdown/chat-markdown-tail/chat-markdown-tail"
}
},
"usingComponents": {
"t-chat-markdown": "tdesign-miniprogram/chat-markdown/chat-markdown"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@
</block>
<block wx:else>
<view class="{{classPrefix}}__assistant">
<t-chat-markdown content="{{textInfo}}" options="{{markdownProps && markdownProps.options}}" bindclick="onMarkdownClick"></t-chat-markdown>
<t-chat-markdown
content="{{textInfo}}"
options="{{markdownProps && markdownProps.options}}"
streaming="{{markdownProps && markdownProps.streaming}}"
generic:tail-component="tail-component"
bindclick="onMarkdownClick"
></t-chat-markdown>
</view>
</block>
</view>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Component({
properties: {},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"component": true,
"styleIsolation": "apply-shared"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<!-- 自定义光标组件示例:渲染一个彩色方块光标 -->
<text class="custom-tail">●</text>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* 自定义光标样式:蓝色渐变闪烁 */
.custom-tail {
display: inline-block;
color: #0052d9;
font-weight: bold;
animation: custom-tail-blink 0.8s ease-in-out infinite;
}

@keyframes custom-tail-blink {
0%, 100% { opacity: 1; }
50% { opacity: 0.2; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ Component({
},
],
},
markdownProps: { streaming: { hasNextChunk: true, tail: true } },
chatId: getUniqueKey(),
};

Expand All @@ -208,6 +209,7 @@ Component({
complete() {
that.setData({
'chatList[0].message.status': 'complete',
'chatList[0].markdownProps': {},
loading: false,
});
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
{
"component": true,
"styleIsolation": "shared",
"componentGenerics": {
"tail-component": {
"default": "./custom-tail/custom-tail"
}
},
"usingComponents": {
"custom-tail": "./custom-tail/custom-tail",
"t-chat-message": "tdesign-miniprogram/chat-message/chat-message",
"t-chat-content": "tdesign-miniprogram/chat-content/chat-content",
"t-chat": "tdesign-miniprogram/chat-list/chat-list",
"t-chat-sender": "tdesign-miniprogram/chat-sender/chat-sender",
"t-chat-actionbar": "tdesign-miniprogram/chat-actionbar/chat-actionbar",
"t-toast": "tdesign-miniprogram/toast/toast"
}
}
}
18 changes: 16 additions & 2 deletions packages/pro-components/chat/chat-list/_example/docs/index.wxml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,26 @@
avatar="{{item.avatar || ''}}"
name="{{item.name || ''}}"
datetime="{{item.datetime || ''}}"
content="{{item.message.content}}"
role="{{item.message.role}}"
chatContentProps="{{chatContentProps}}"
placement="{{item.message.role === 'user' ? 'right' : 'left'}}"
bind:message-longpress="showPopover"
>
<view slot="content">
<block
wx:for="{{item.message.content}}"
wx:for-item="contentItem"
wx:for-index="contentIndex"
wx:key="contentIndex"
>
<t-chat-content
wx:if="{{contentItem.type === 'text' || contentItem.type === 'markdown'}}"
content="{{contentItem}}"
role="{{item.message.role}}"
markdownProps="{{item.markdownProps}}"
generic:tail-component="custom-tail"
/>
</block>
</view>
<t-chat-actionbar
wx:if="{{chatIndex !== chatList.length - 1 && item.message.status === 'complete' && item.message.role === 'assistant'}}"
slot="actionbar"
Expand Down
5 changes: 5 additions & 0 deletions packages/pro-components/chat/chat-markdown/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ isComponent: true

{{ refer }}

### 05 流式输出光标

{{ tail }}

## API

### ChatMarkdown Props
Expand All @@ -63,6 +67,7 @@ isComponent: true
style | Object | - | 样式 | N
custom-style | Object | - | 样式,一般用于开启虚拟化组件节点场景 | N
content | String | - | 必需。markdown 内容文本 | Y
streaming | Object | - | 流式输出配置,控制光标显示。TS 类型:`TdChatStreamingConfig` `interface TdChatStreamingConfig { hasNextChunk?: boolean; tail?: boolean \| { content?: string } }`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/blob/develop/packages/pro-components/chat/chat-markdown/type.ts) | N
options | Object | { gfm: true, pedantic: false, breaks: true } | Markdown 解析器基础配置。TS 类型:`TdChatContentMDOptions ` `interface TdChatContentMDOptions {gfm?: boolean; pedantic?: boolean; smartLists?: boolean; breaks?: boolean}`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/blob/develop/packages/pro-components/chat/chat-markdown/type.ts) | N

### ChatMarkdown Events
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"code": "./code",
"sheet": "./sheet",
"url": "./url",
"refer": "./refer"
"refer": "./refer",
"tail": "./tail"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,7 @@
<t-demo title="04 引用">
<refer />
</t-demo>
<t-demo title="05 流式输出 Tail 光标">
<tail />
</t-demo>
</view>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Component({
properties: {},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"component": true,
"styleIsolation": "apply-shared"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<!-- 自定义光标组件示例:渲染一个彩色方块光标 -->
<text class="custom-tail">●</text>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* 自定义光标样式:蓝色渐变闪烁 */
.custom-tail {
display: inline-block;
color: #0052d9;
font-weight: bold;
animation: custom-tail-blink 0.8s ease-in-out infinite;
}

@keyframes custom-tail-blink {
0%, 100% { opacity: 1; }
50% { opacity: 0.2; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import markdownData from '../base/mock2.js';

const CHUNK_SIZE = 5;
const INTERVAL_MS = 80;

Page({
data: {
content: '',
streaming: { hasNextChunk: false, tail: true },
},

onLoad() {
this.startStreaming();
},

startStreaming() {
let index = 0;

this.setData({
content: '',
streaming: { hasNextChunk: true, tail: true },
});

const timer = setInterval(() => {
index += CHUNK_SIZE;
const isDone = index >= markdownData.length;
this.setData({
content: markdownData.slice(0, index),
streaming: { hasNextChunk: !isDone, tail: true },
});
if (isDone) clearInterval(timer);
}, INTERVAL_MS);
},

handleReplay() {
this.startStreaming();
},

handleNodeTap(e) {
const { node } = e.detail;
if (node && node.type === 'image') {
wx.previewImage({ urls: [node.href], current: node.href });
}
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"usingComponents": {
"t-chat-markdown": "tdesign-miniprogram/chat-markdown/chat-markdown",
"custom-tail": "./custom-tail/custom-tail"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<view class="chat-example-block">
<!-- 默认光标(使用内置 chat-markdown-tail 组件) -->
<view style="margin-bottom: 16px">
<view style="font-size: 12px; color: #888; margin-bottom: 8px">默认光标</view>
<t-chat-markdown content="{{content}}" streaming="{{streaming}}" bind:click="handleNodeTap" />
</view>
<!-- 自定义 tail-component(通过 generic:tail-component 传入) -->
<view>
<view style="font-size: 12px; color: #888; margin-bottom: 8px">自定义光标组件</view>
<t-chat-markdown
content="{{content}}"
streaming="{{streaming}}"
generic:tail-component="custom-tail"
bind:click="handleNodeTap"
/>
</view>
<button bindtap="handleReplay" style="margin-top: 16px">重新播放</button>
</view>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.chat-example-block {
background-color: var(--td-bg-color-container);
padding: 32rpx;
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
{
"component": true,
"styleIsolation": "apply-shared",
"componentGenerics": {
"tail-component": {
"default": "../chat-markdown-tail/chat-markdown-tail"
}
},
"usingComponents": {
"chat-markdown-table": "../chat-markdown-table/chat-markdown-table",
"chat-markdown-code": "../chat-markdown-code/chat-markdown-code",
"chat-markdown-node": "./chat-markdown-node"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<!-- blocks -->
<block wx:if="{{item.type==='heading'}}">
<view class="{{classPrefix}}-h {{ classPrefix}}-h{{item.depth}}" data-index="{{i}}" bindtap="nodeClick">
<chat-markdown-node nodes="{{item.tokens}}" />
<chat-markdown-node nodes="{{item.tokens}}" generic:tail-component="tail-component" />
</view>
</block>
<block wx:elif="{{item.type==='list'}}">
Expand All @@ -15,7 +15,7 @@
<block wx:for="{{item.items}}" wx:for-item="li" wx:for-index="j" wx:key="j">
<view class="{{classPrefix}}-list-item">
<block wx:if="{{li.tokens && li.tokens.length}}">
<chat-markdown-node nodes="{{li.tokens}}" />
<chat-markdown-node nodes="{{li.tokens}}" generic:tail-component="tail-component" />
</block>
<block wx:else>{{''+li.text+''}}</block>
</view>
Expand All @@ -24,7 +24,7 @@
</block>
<block wx:elif="{{item.type==='paragraph'}}">
<view class="{{classPrefix}}-p" data-index="{{i}}" bindtap="nodeClick">
<chat-markdown-node nodes="{{item.tokens}}" />
<chat-markdown-node nodes="{{item.tokens}}" generic:tail-component="tail-component" />
</view>
</block>
<block wx:elif="{{item.type==='image'}}">
Expand All @@ -37,7 +37,7 @@
</block>
<block wx:elif="{{item.type==='blockquote'}}">
<view class="{{classPrefix}}-blockquote" data-index="{{i}}" bindtap="nodeClick"
><chat-markdown-node nodes="{{item.tokens}}" />
><chat-markdown-node nodes="{{item.tokens}}" generic:tail-component="tail-component" />
</view>
</block>
<block wx:elif="{{item.type==='code'}}">
Expand All @@ -53,39 +53,42 @@
bindtap="nodeClick"
>
<block wx:if="{{item.tokens && item.tokens.length}}">
<chat-markdown-node nodes="{{item.tokens}}" />
<chat-markdown-node nodes="{{item.tokens}}" generic:tail-component="tail-component" />
</block>
<block wx:else>
{{''+item.raw+''}}
<tail-component wx:if="{{item.isTail}}" />
</block>
<block wx:else>{{''+item.raw+''}}</block>
</view>
</block>
<block wx:elif="{{item.type==='strong'}}">
<view class="{{classPrefix}}-strong {{classPrefix}}-inline" data-index="{{i}}" bindtap="nodeClick">
<block wx:if="{{item.tokens && item.tokens.length}}">
<chat-markdown-node nodes="{{item.tokens}}" />
<chat-markdown-node nodes="{{item.tokens}}" generic:tail-component="tail-component" />
</block>
<block wx:else>{{''+item.text+''}}</block>
</view>
</block>
<block wx:elif="{{item.type==='em'}}">
<view class="{{classPrefix}}-em {{classPrefix}}-inline" data-index="{{i}}" bindtap="nodeClick">
<block wx:if="{{item.tokens && item.tokens.length}}">
<chat-markdown-node nodes="{{item.tokens}}" />
<chat-markdown-node nodes="{{item.tokens}}" generic:tail-component="tail-component" />
</block>
<block wx:else>{{''+item.text+''}}</block>
</view>
</block>
<block wx:elif="{{item.type==='del'}}">
<view class="{{classPrefix}}-del {{classPrefix}}-inline" data-index="{{i}}" bindtap="nodeClick">
<block wx:if="{{item.tokens && item.tokens.length}}">
<chat-markdown-node nodes="{{item.tokens}}" />
<chat-markdown-node nodes="{{item.tokens}}" generic:tail-component="tail-component" />
</block>
<block wx:else>{{''+item.text+''}}</block>
</view>
</block>
<block wx:elif="{{item.type==='link'}}">
<view class="{{classPrefix}}-link {{classPrefix}}-inline" data-index="{{i}}" bindtap="nodeClick">
<block wx:if="{{item.tokens && item.tokens.length}}">
<chat-markdown-node nodes="{{item.tokens}}" />
<chat-markdown-node nodes="{{item.tokens}}" generic:tail-component="tail-component" />
</block>
</view>
</block>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"component": true,
"styleIsolation": "apply-shared"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { SuperComponent, wxComponent, ComponentsOptionsType } from '../../../../components/common/src/index';
import config from '../../../../components/common/config';

const { prefix } = config;
const name = `${prefix}-chat-markdown`;

@wxComponent()
export default class ChatMarkdownTail extends SuperComponent {
options: ComponentsOptionsType = {};

properties = {
/** 光标字符内容,由 chat-markdown 内部注入,默认 ▋ */
content: {
type: String,
value: '▋',
},
};

data = {
classPrefix: name,
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<text class="t-chat-markdown-tail">{{content}}</text>
Loading
Loading