@opentiny/vue-docs 3.24.5 → 3.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/demos/apis/button.js +15 -0
  2. package/demos/apis/calendar-view.js +3 -2
  3. package/demos/apis/chart-demo.js +1 -1
  4. package/demos/apis/chart-docs.js +1 -1
  5. package/demos/apis/chart-events.js +1 -1
  6. package/demos/apis/chart-question.js +1 -1
  7. package/demos/apis/chart.js +1 -1
  8. package/demos/apis/form.js +3 -0
  9. package/demos/apis/grid.js +76 -16
  10. package/demos/mobile-first/app/button/type.vue +1 -1
  11. package/demos/mobile-first/app/button/webdoc/button.js +2 -2
  12. package/demos/pc/app/action-menu/basic-usage-composition-api.vue +1 -1
  13. package/demos/pc/app/action-menu/basic-usage.vue +1 -1
  14. package/demos/pc/app/action-menu/card-mode-composition-api.vue +1 -1
  15. package/demos/pc/app/action-menu/card-mode.vue +1 -1
  16. package/demos/pc/app/action-menu/disabled-composition-api.vue +2 -2
  17. package/demos/pc/app/action-menu/disabled.vue +2 -2
  18. package/demos/pc/app/action-menu/events-composition-api.vue +1 -1
  19. package/demos/pc/app/action-menu/events.vue +1 -1
  20. package/demos/pc/app/action-menu/icon-composition-api.vue +2 -2
  21. package/demos/pc/app/action-menu/icon.vue +2 -2
  22. package/demos/pc/app/action-menu/max-show-num-composition-api.vue +1 -1
  23. package/demos/pc/app/action-menu/max-show-num.vue +1 -1
  24. package/demos/pc/app/action-menu/more-text-composition-api.vue +1 -1
  25. package/demos/pc/app/action-menu/more-text.vue +1 -1
  26. package/demos/pc/app/action-menu/popper-class-composition-api.vue +1 -1
  27. package/demos/pc/app/action-menu/popper-class.vue +1 -1
  28. package/demos/pc/app/action-menu/slot-item-composition-api.vue +1 -1
  29. package/demos/pc/app/action-menu/slot-item.vue +1 -1
  30. package/demos/pc/app/action-menu/spacing-composition-api.vue +1 -1
  31. package/demos/pc/app/action-menu/spacing.vue +1 -1
  32. package/demos/pc/app/action-menu/text-field-composition-api.vue +1 -1
  33. package/demos/pc/app/action-menu/text-field.spec.ts +1 -1
  34. package/demos/pc/app/action-menu/text-field.vue +1 -1
  35. package/demos/pc/app/button/icon-composition-api.vue +3 -1
  36. package/demos/pc/app/button/icon.vue +3 -1
  37. package/demos/pc/app/button/webdoc/button.js +3 -2
  38. package/demos/pc/app/calendar-view/calendar-mode-composition-api.vue +7 -1
  39. package/demos/pc/app/calendar-view/calendar-mode.spec.ts +3 -0
  40. package/demos/pc/app/calendar-view/calendar-mode.vue +7 -1
  41. package/demos/pc/app/carousel/webdoc/carousel.js +0 -18
  42. package/demos/pc/app/date-panel/custom-week.spec.ts +2 -2
  43. package/demos/pc/app/grid/base/basic-usage-composition-api.vue +1 -17
  44. package/demos/pc/app/grid/custom/column-fixed.spec.js +2 -1
  45. package/demos/pc/app/grid/custom/page-size.spec.js +1 -1
  46. package/demos/pc/app/grid/data-source/request-service.spec.js +1 -1
  47. package/demos/pc/app/grid/data-source/static-data.spec.js +1 -1
  48. package/demos/pc/app/grid/edit/scrollbar-not-blur-composition-api.vue +119 -0
  49. package/demos/pc/app/grid/edit/scrollbar-not-blur.spec.ts +28 -0
  50. package/demos/pc/app/grid/edit/scrollbar-not-blur.vue +129 -0
  51. package/demos/pc/app/grid/editor/custom-edit.spec.js +7 -2
  52. package/demos/pc/app/grid/empty/empty-data-iscenter.spec.js +1 -1
  53. package/demos/pc/app/grid/event/toolbar-button-click-event.spec.js +1 -1
  54. package/demos/pc/app/grid/expand/expand-trigger-slot-composition-api.vue +85 -0
  55. package/demos/pc/app/grid/expand/expand-trigger-slot.spec.ts +11 -0
  56. package/demos/pc/app/grid/expand/expand-trigger-slot.vue +95 -0
  57. package/demos/pc/app/grid/expand/set-row-expansion.spec.js +4 -0
  58. package/demos/pc/app/grid/filter/default-filter-composition-api.vue +6 -0
  59. package/demos/pc/app/grid/filter/default-filter.vue +6 -0
  60. package/demos/pc/app/grid/filter/default-relation.spec.js +1 -1
  61. package/demos/pc/app/grid/filter/server-filter.spec.js +1 -1
  62. package/demos/pc/app/grid/fixed/right-fixed-composition-api.vue +4 -4
  63. package/demos/pc/app/grid/fixed/right-fixed.vue +4 -4
  64. package/demos/pc/app/grid/footer/footer-summation-empty.spec.js +0 -1
  65. package/demos/pc/app/grid/large-data/full-data-loading.spec.js +10 -3
  66. package/demos/pc/app/grid/large-data/virtual-rolling.spec.js +9 -2
  67. package/demos/pc/app/grid/mouse-keyboard/keyboard-navigation.spec.js +4 -1
  68. package/demos/pc/app/grid/renderer/inner-renderer-date-composition-api.vue +4 -3
  69. package/demos/pc/app/grid/renderer/inner-renderer-date.spec.js +2 -2
  70. package/demos/pc/app/grid/renderer/inner-renderer-date.vue +3 -3
  71. package/demos/pc/app/grid/renderer/inner-renderer.spec.js +4 -0
  72. package/demos/pc/app/grid/size/max-min-grid-height.spec.js +2 -2
  73. package/demos/pc/app/grid/sort/combinations-sort.spec.js +2 -2
  74. package/demos/pc/app/grid/webdoc/grid-edit.js +12 -0
  75. package/demos/pc/app/grid/webdoc/grid-empty.js +1 -1
  76. package/demos/pc/app/grid/webdoc/grid-expand.js +11 -0
  77. package/demos/pc/app/icon/iconGroups.js +1 -0
  78. package/demos/pc/app/popeditor/conditions.spec.ts +1 -1
  79. package/demos/pc/app/select/nest-grid-remote.spec.ts +3 -3
  80. package/demos/pc/app/select/nest-grid.spec.ts +1 -1
  81. package/demos/pc/app/select/nest-radio-grid-much-data.spec.ts +5 -7
  82. package/demos/pc/webdoc/changelog-en.md +270 -197
  83. package/demos/pc/webdoc/changelog.md +82 -256
  84. package/package.json +19 -23
  85. package/playground/App.vue +2 -2
  86. package/src/App.vue +1 -18
  87. package/src/components/float-settings.vue +0 -13
  88. package/src/composable/utils.ts +2 -162
  89. package/src/i18n/index.js +1 -2
  90. package/src/main.js +1 -10
  91. package/src/router.js +0 -12
  92. package/src/tools/appData.js +2 -11
  93. package/src/views/components-doc/common.vue +0 -6
  94. package/src/components/MessageCard.vue +0 -117
  95. package/src/components/tiny-robot-chat.vue +0 -128
  96. package/src/composable/DifyModelProvider.ts +0 -65
  97. package/src/composable/useTinyRobot.ts +0 -167
  98. package/src/views/comprehensive/Demo.vue +0 -211
  99. package/src/views/comprehensive/index.vue +0 -380
  100. package/src/views/comprehensive/products.json +0 -99
  101. package/src/views/comprehensive/types/index.ts +0 -37
  102. package/src/views/remoter/index.vue +0 -63
  103. package/src/views/remoter/sound.vue +0 -349
  104. /package/demos/pc/app/grid/expand/{expand-config.spec.js → expand-config.spec.ts} +0 -0
@@ -1,349 +0,0 @@
1
- <template>
2
- <div class="sound-container">
3
- <div class="messages-container" ref="messagesContainer">
4
- <template v-if="messages && messages.length > 0">
5
- <message-card
6
- v-for="(msg, index) in messages"
7
- :key="index"
8
- :role="msg.role === 'system' ? 'assistant' : msg.role"
9
- :message="msg.content"
10
- :timestamp="messageTimestamps[index]"
11
- />
12
- </template>
13
- <div v-else class="empty-message">
14
- <p>暂无对话记录</p>
15
- </div>
16
- </div>
17
- <div class="sound-box">
18
- <div class="recording-status" v-show="isTalk">
19
- <div class="wave-animation"></div>
20
- <span>{{ recordingTime }}s</span>
21
- </div>
22
- <tiny-button
23
- @touchstart.prevent="handleStart"
24
- @touchend.prevent="handleEnd"
25
- @touchcancel.prevent="handleEnd"
26
- :type="isTalk ? 'danger' : 'info'"
27
- class="talk-button"
28
- size="large"
29
- :reset-time="0"
30
- :disabled="!isSupported"
31
- >
32
- {{ buttonText }}
33
- </tiny-button>
34
- </div>
35
- </div>
36
- </template>
37
-
38
- <script setup lang="ts">
39
- import { ref, computed, onUnmounted, watch, nextTick } from 'vue'
40
- import { TinyButton, TinyNotify } from '@opentiny/vue'
41
- import { useTinyRobot } from '../../composable/useTinyRobot'
42
- import MessageCard from '../../components/MessageCard.vue'
43
-
44
- // 类型定义
45
- interface SpeechRecognitionResult {
46
- [index: number]: {
47
- transcript: string
48
- confidence: number
49
- }
50
- isFinal?: boolean
51
- length: number
52
- }
53
-
54
- interface SpeechRecognitionResultList {
55
- [index: number]: SpeechRecognitionResult
56
- length: number
57
- }
58
-
59
- interface SpeechRecognitionEvent extends Event {
60
- results: SpeechRecognitionResultList
61
- }
62
-
63
- interface SpeechRecognitionErrorEvent extends Event {
64
- error: string
65
- message: string
66
- }
67
-
68
- // 获取SpeechRecognition构造函数
69
- const getSpeechRecognition = () => {
70
- const SpeechRecognition =
71
- (window as any).SpeechRecognition ||
72
- (window as any).webkitSpeechRecognition ||
73
- (window as any).mozSpeechRecognition ||
74
- (window as any).msSpeechRecognition
75
- return SpeechRecognition
76
- }
77
-
78
- // 状态管理
79
- const isTalk = ref(false)
80
- const isSupported = ref(false)
81
- const recordingTime = ref(0)
82
- const maxRecordingTime = 60
83
- let recognition: any = null
84
- let recordingTimer: number | null = null
85
- const messagesContainer = ref<HTMLElement | null>(null)
86
- const messageTimestamps = ref<number[]>([])
87
- const { sendMessage, messages } = useTinyRobot()
88
- const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)
89
-
90
- // 计算属性
91
- const buttonText = computed(() => {
92
- if (!isSupported.value) return '当前浏览器不支持语音识别'
93
- if (isTalk.value) return `录音中 ${recordingTime.value}s`
94
- return '长按说话'
95
- })
96
-
97
- // 监听消息变化,更新时间戳和自动滚动
98
- watch(
99
- () => messages.value,
100
- async (newMessages) => {
101
- if (!newMessages) return
102
-
103
- // 更新时间戳
104
- if (messageTimestamps.value.length < newMessages.length) {
105
- const timestamp = Date.now()
106
- messageTimestamps.value = newMessages.map((_, index) => messageTimestamps.value[index] || timestamp)
107
- }
108
-
109
- // 自动滚动到底部
110
- await nextTick()
111
- if (messagesContainer.value) {
112
- messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight
113
- }
114
- },
115
- { deep: true }
116
- )
117
-
118
- // 初始化语音识别
119
- const initSpeechRecognition = () => {
120
- const SpeechRecognition = getSpeechRecognition()
121
-
122
- if (SpeechRecognition) {
123
- isSupported.value = true
124
- recognition = new SpeechRecognition()
125
- recognition.lang = 'zh-CN'
126
- recognition.continuous = false
127
- recognition.interimResults = false
128
- recognition.maxAlternatives = 1
129
-
130
- // Safari 需要特殊处理
131
- if (isSafari) {
132
- recognition.interimResults = true
133
- }
134
-
135
- let finalTranscript = ''
136
-
137
- recognition.addEventListener('result', (event: SpeechRecognitionEvent) => {
138
- const transcript = event.results[0][0].transcript
139
- if (transcript.trim()) {
140
- finalTranscript = transcript
141
- }
142
- })
143
-
144
- recognition.addEventListener('end', () => {
145
- stopRecording()
146
- // 确保在录音结束时发送消息
147
- if (finalTranscript.trim()) {
148
- sendMessage(finalTranscript)
149
- finalTranscript = ''
150
- }
151
- })
152
-
153
- recognition.addEventListener('error', (event: SpeechRecognitionErrorEvent) => {
154
- handleRecognitionError(event)
155
- finalTranscript = ''
156
- })
157
- } else {
158
- isSupported.value = false
159
- TinyNotify({
160
- type: 'error',
161
- title: '提示',
162
- message: '您的浏览器不支持语音识别,请使用Chrome、Safari或Edge浏览器',
163
- position: 'top-right',
164
- duration: 5000
165
- })
166
- }
167
- }
168
-
169
- // 错误处理
170
- const handleRecognitionError = (event: SpeechRecognitionErrorEvent) => {
171
- stopRecording()
172
- let errorMessage = '语音识别出错'
173
-
174
- switch (event.error) {
175
- case 'not-allowed':
176
- errorMessage = '请允许浏览器使用麦克风'
177
- break
178
- case 'no-speech':
179
- errorMessage = '未检测到语音,请重试'
180
- break
181
- case 'network':
182
- errorMessage = '网络连接出错,请检查网络后重试'
183
- break
184
- case 'aborted':
185
- return // 用户主动取消,不显示错误
186
- default:
187
- errorMessage = `语音识别失败: ${event.message || '未知错误'}`
188
- }
189
-
190
- TinyNotify({
191
- type: 'error',
192
- title: '语音识别出错',
193
- message: errorMessage,
194
- position: 'top-right',
195
- duration: 3000
196
- })
197
- }
198
-
199
- // 开始录音
200
- const handleStart = async (event: TouchEvent) => {
201
- event.preventDefault()
202
- event.stopPropagation()
203
-
204
- if (!isSupported.value) {
205
- TinyNotify({
206
- type: 'error',
207
- title: '提示',
208
- message: '当前浏览器不支持语音识别',
209
- position: 'top-right',
210
- duration: 3000
211
- })
212
- return
213
- }
214
-
215
- if (isTalk.value) return
216
-
217
- try {
218
- recognition.start()
219
- isTalk.value = true
220
- recordingTime.value = 0
221
- startRecordingTimer()
222
- } catch (error) {
223
- handleRecognitionError({
224
- error: 'start_error',
225
- message: '启动语音识别失败,请重试'
226
- } as SpeechRecognitionErrorEvent)
227
- }
228
- }
229
-
230
- // 结束录音
231
- const handleEnd = () => {
232
- if (!isTalk.value) return
233
- try {
234
- recognition.stop()
235
- } catch (error) {
236
- console.error('停止录音失败:', error)
237
- }
238
- stopRecording()
239
- }
240
-
241
- // 开始计时
242
- const startRecordingTimer = () => {
243
- recordingTimer = window.setInterval(() => {
244
- recordingTime.value++
245
- if (recordingTime.value >= maxRecordingTime) {
246
- handleEnd()
247
- TinyNotify({
248
- type: 'warning',
249
- title: '提示',
250
- message: '已达到最大录音时长',
251
- position: 'top-right',
252
- duration: 3000
253
- })
254
- }
255
- }, 1000)
256
- }
257
-
258
- // 停止录音
259
- const stopRecording = () => {
260
- isTalk.value = false
261
- if (recordingTimer) {
262
- clearInterval(recordingTimer)
263
- recordingTimer = null
264
- }
265
- }
266
-
267
- // 初始化
268
- initSpeechRecognition()
269
-
270
- // 组件卸载时清理
271
- onUnmounted(() => {
272
- if (recordingTimer) {
273
- clearInterval(recordingTimer)
274
- }
275
- if (recognition) {
276
- try {
277
- recognition.abort()
278
- } catch (error) {
279
- console.error('清理语音识别失败:', error)
280
- }
281
- }
282
- })
283
- </script>
284
-
285
- <style scoped lang="less">
286
- .sound-container {
287
- display: flex;
288
- flex-direction: column;
289
- height: 100vh;
290
- position: relative;
291
-
292
- .messages-container {
293
- flex: 1;
294
- overflow-y: auto;
295
- padding: 16px;
296
- margin-bottom: 120px;
297
-
298
- .empty-message {
299
- text-align: center;
300
- color: #999;
301
- padding: 20px;
302
- }
303
- }
304
-
305
- .sound-box {
306
- position: fixed;
307
- bottom: 0;
308
- left: 0;
309
- right: 0;
310
- margin: 10px;
311
- background: white;
312
- padding: 10px;
313
- box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
314
-
315
- .recording-status {
316
- text-align: center;
317
- margin-bottom: 10px;
318
-
319
- .wave-animation {
320
- width: 100px;
321
- height: 20px;
322
- margin: 0 auto 5px;
323
- background: linear-gradient(90deg, #ff4d4f 25%, #ff7875 50%, #ff4d4f 75%);
324
- background-size: 200% 100%;
325
- animation: wave 2s linear infinite;
326
- }
327
- }
328
-
329
- .talk-button {
330
- width: 100%;
331
- margin: 20px 0;
332
- transition: all 0.3s;
333
-
334
- &:active {
335
- transform: scale(0.98);
336
- }
337
- }
338
- }
339
- }
340
-
341
- @keyframes wave {
342
- 0% {
343
- background-position: 100% 50%;
344
- }
345
- 100% {
346
- background-position: 0% 50%;
347
- }
348
- }
349
- </style>