@opentiny/tiny-robot 0.2.0-alpha.1 → 0.2.0-alpha.2

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 (56) hide show
  1. package/dist/action-group/index.type.d.ts +1 -0
  2. package/dist/bubble/index.d.ts +2 -2
  3. package/dist/bubble/index.type.d.ts +16 -18
  4. package/dist/feedback/index.vue.d.ts +2 -2
  5. package/dist/icon-button/index.type.d.ts +2 -3
  6. package/dist/icon-button/index.vue.d.ts +3 -3
  7. package/dist/node_modules/.pnpm/@vueuse_core@13.1.0_vue@3.5.13/node_modules/@vueuse/core/index.js +262 -142
  8. package/dist/node_modules/.pnpm/@vueuse_shared@13.1.0_vue@3.5.13/node_modules/@vueuse/shared/index.js +96 -39
  9. package/dist/packages/components/src/action-group/ActionGroup.vue.js +2 -2
  10. package/dist/packages/components/src/action-group/ActionGroup.vue2.js +96 -72
  11. package/dist/packages/components/src/bubble/Bubble.vue.js +7 -0
  12. package/dist/packages/components/src/bubble/Bubble.vue2.js +76 -0
  13. package/dist/packages/components/src/bubble/BubbleList.vue.js +7 -0
  14. package/dist/packages/components/src/bubble/BubbleList.vue2.js +50 -0
  15. package/dist/packages/components/src/bubble/index.js +2 -2
  16. package/dist/packages/components/src/container/index.vue.js +2 -2
  17. package/dist/packages/components/src/container/index.vue2.js +36 -36
  18. package/dist/packages/components/src/feedback/index.vue.js +2 -2
  19. package/dist/packages/components/src/feedback/index.vue2.js +72 -71
  20. package/dist/packages/components/src/icon-button/index.vue.js +2 -2
  21. package/dist/packages/components/src/icon-button/index.vue2.js +9 -27
  22. package/dist/packages/components/src/sender/components/TemplateEditor.vue.js +2 -2
  23. package/dist/packages/components/src/sender/components/TemplateEditor.vue2.js +137 -83
  24. package/dist/sender/index.vue.d.ts +2 -2
  25. package/dist/style.css +1 -1
  26. package/package.json +3 -3
  27. package/src/action-group/ActionGroup.vue +38 -23
  28. package/src/action-group/index.type.ts +1 -0
  29. package/src/bubble/{bubble.vue → Bubble.vue} +13 -97
  30. package/src/bubble/BubbleList.vue +55 -0
  31. package/src/bubble/index.ts +2 -2
  32. package/src/bubble/index.type.ts +7 -21
  33. package/src/container/index.vue +10 -35
  34. package/src/feedback/index.vue +14 -14
  35. package/src/icon-button/index.type.ts +2 -3
  36. package/src/icon-button/index.vue +16 -10
  37. package/src/sender/components/TemplateEditor.vue +301 -110
  38. package/dist/bubble/components/actions/copy.vue.d.ts +0 -10
  39. package/dist/bubble/components/actions/index.d.ts +0 -2
  40. package/dist/bubble/components/actions/refresh.vue.d.ts +0 -2
  41. package/dist/bubble/useScroll.d.ts +0 -4
  42. package/dist/packages/components/src/bubble/bubble-list.vue.js +0 -7
  43. package/dist/packages/components/src/bubble/bubble-list.vue2.js +0 -37
  44. package/dist/packages/components/src/bubble/bubble.vue.js +0 -7
  45. package/dist/packages/components/src/bubble/bubble.vue2.js +0 -118
  46. package/dist/packages/components/src/bubble/components/actions/copy.vue.js +0 -7
  47. package/dist/packages/components/src/bubble/components/actions/copy.vue2.js +0 -35
  48. package/dist/packages/components/src/bubble/components/actions/refresh.vue.js +0 -7
  49. package/dist/packages/components/src/bubble/components/actions/refresh.vue2.js +0 -16
  50. package/dist/packages/components/src/bubble/useScroll.js +0 -13
  51. package/src/bubble/bubble-list.vue +0 -42
  52. package/src/bubble/components/actions/copy.vue +0 -54
  53. package/src/bubble/components/actions/index.ts +0 -2
  54. package/src/bubble/components/actions/refresh.vue +0 -31
  55. package/src/bubble/useScroll.ts +0 -14
  56. /package/dist/bubble/{bubble-list.vue.d.ts → BubbleList.vue.d.ts} +0 -0
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { ref, computed, nextTick, watch } from 'vue'
2
+ import { ref, nextTick, watch, onMounted } from 'vue'
3
3
  import { TemplatePart, TemplateEditorProps, TemplateEditorEmits, TemplateEditorExpose } from '../index.type'
4
4
 
5
5
  // 使用类型定义props
@@ -11,21 +11,26 @@ const emit = defineEmits<TemplateEditorEmits>()
11
11
  // 编辑器DOM引用
12
12
  const editorRef = ref<HTMLElement | null>(null)
13
13
 
14
- // 输入框引用集合
15
- // eslint-disable-next-line
16
- const inputRefs = ref<any>({})
14
+ // 可编辑元素引用集合
15
+ const editableRefs = ref<Record<number, HTMLElement>>({})
17
16
 
18
17
  // 当前激活的输入块索引
19
18
  const activeFieldIndex = ref<number>(-1)
20
19
 
21
- // 解析模板,将其分解为普通文本和可编辑字段
22
- const templateParts = computed<TemplatePart[]>(() => {
23
- // TODO: 如果已有值,使用现有值填充模板
24
- if (props.value) {
25
- return parseValueIntoTemplate()
26
- }
20
+ // 是否有内容标志
21
+ const hasContent = ref(false)
22
+
23
+ // 标记是否是用户手动编辑
24
+ const isUserEditing = ref(false)
27
25
 
28
- // 否则使用模板解析
26
+ // 标记是否是内部更新,避免循环更新
27
+ const isInternalUpdate = ref(false)
28
+
29
+ // 使用ref代替computed属性,作为组件的主要状态来源
30
+ const editableParts = ref<TemplatePart[]>([])
31
+
32
+ // 解析模板,将其分解为普通文本和可编辑字段
33
+ const parseTemplate = (template: string): TemplatePart[] => {
29
34
  const parts: TemplatePart[] = []
30
35
  let currentIndex = 0
31
36
  let fieldIndex = 0
@@ -34,18 +39,18 @@ const templateParts = computed<TemplatePart[]>(() => {
34
39
  const regex = /\[(.*?)\]/g
35
40
  let match
36
41
 
37
- while ((match = regex.exec(props.template)) !== null) {
42
+ while ((match = regex.exec(template)) !== null) {
38
43
  // 添加匹配前的普通文本
39
44
  if (match.index > currentIndex) {
40
45
  parts.push({
41
- content: props.template.substring(currentIndex, match.index),
46
+ content: template.substring(currentIndex, match.index),
42
47
  isField: false,
43
48
  })
44
49
  }
45
50
 
46
- // 添加匹配的字段
51
+ // 添加匹配的字段,将placeholder作为默认内容
47
52
  parts.push({
48
- content: '',
53
+ content: match[1], // 使用占位符作为默认内容
49
54
  placeholder: match[1],
50
55
  isField: true,
51
56
  fieldIndex: fieldIndex++,
@@ -55,134 +60,319 @@ const templateParts = computed<TemplatePart[]>(() => {
55
60
  }
56
61
 
57
62
  // 添加剩余的普通文本
58
- if (currentIndex < props.template.length) {
63
+ if (currentIndex < template.length) {
59
64
  parts.push({
60
- content: props.template.substring(currentIndex),
65
+ content: template.substring(currentIndex),
61
66
  isField: false,
62
67
  })
63
68
  }
64
69
 
65
70
  return parts
66
- })
71
+ }
72
+
73
+ // 初始化editableParts
74
+ const initializeEditableParts = (): void => {
75
+ editableParts.value = parseTemplate(props.template)
76
+ if (props.value) {
77
+ updatePartsFromValue(props.value)
78
+ }
79
+ }
67
80
 
68
- // 解析现有值填充到模板中
69
- const parseValueIntoTemplate = (): TemplatePart[] => {
70
- // 在实际应用中,这里应该根据模板和现有值进行匹配
71
- return templateParts.value
81
+ // 从value更新各个部分的内容
82
+ const updatePartsFromValue = (value: string): void => {
83
+ if (!value || isInternalUpdate.value) return
84
+
85
+ // 仅在值确实不同时才更新,避免不必要的处理
86
+ const currentValue = generateValue()
87
+ if (currentValue === value) return
88
+
89
+ // 创建一个临时的解析结果用于比较
90
+ const templateStructure = parseTemplate(props.template)
91
+
92
+ // 计算模板的静态部分(非字段部分)
93
+ const staticParts: string[] = []
94
+
95
+ templateStructure.forEach((part) => {
96
+ if (!part.isField) {
97
+ staticParts.push(part.content)
98
+ } else {
99
+ // 用一个占位符标记字段位置
100
+ staticParts.push(`__FIELD_${part.fieldIndex}__`)
101
+ }
102
+ })
103
+
104
+ // 使用静态部分作为分隔符,尝试提取字段值
105
+ let remainingValue = value
106
+ let currentFieldIndex = 0
107
+
108
+ // 遍历editableParts,找到字段并更新
109
+ for (let i = 0; i < editableParts.value.length; i++) {
110
+ const part = editableParts.value[i]
111
+
112
+ if (!part.isField) continue
113
+
114
+ // 尝试找到当前字段前的静态部分
115
+ const prevStaticPart = staticParts[currentFieldIndex]
116
+ currentFieldIndex++
117
+
118
+ // 下一个静态部分(如果有)
119
+ const nextStaticPart = staticParts[currentFieldIndex] || ''
120
+
121
+ if (prevStaticPart && remainingValue.startsWith(prevStaticPart)) {
122
+ // 移除前导静态部分
123
+ remainingValue = remainingValue.substring(prevStaticPart.length)
124
+
125
+ // 如果有下一个静态部分,提取中间的字段值
126
+ if (nextStaticPart && remainingValue.includes(nextStaticPart)) {
127
+ const fieldEndIndex = remainingValue.indexOf(nextStaticPart)
128
+ const fieldValue = remainingValue.substring(0, fieldEndIndex)
129
+
130
+ // 更新字段内容
131
+ if (fieldValue) {
132
+ editableParts.value[i].content = fieldValue
133
+
134
+ // 如果当前字段是激活状态,更新DOM内容,但不改变光标位置
135
+ if (activeFieldIndex.value === i && editableRefs.value[i]) {
136
+ // 使用MutationObserver来禁用临时
137
+ isUserEditing.value = true
138
+ // 不要直接设置textContent,避免干扰用户输入
139
+ }
140
+ }
141
+
142
+ // 移除已处理的部分
143
+ remainingValue = remainingValue.substring(fieldEndIndex)
144
+ } else if (!nextStaticPart && remainingValue) {
145
+ // 如果是最后一个字段,则剩余的全部是它的值
146
+ editableParts.value[i].content = remainingValue
147
+ remainingValue = ''
148
+ }
149
+ }
150
+ }
151
+
152
+ // 更新内容状态
153
+ checkHasContent(value)
72
154
  }
73
155
 
74
156
  // 生成完整的文本值
75
157
  const generateValue = (): string => {
76
- return templateParts.value.map((part) => part.content).join('')
158
+ return editableParts.value.map((part) => part.content).join('')
77
159
  }
78
160
 
79
161
  // 更新值并触发事件
80
162
  const updateValue = (): void => {
163
+ isInternalUpdate.value = true
81
164
  const newValue = generateValue()
82
165
  emit('update:value', newValue)
83
166
  emit('input', newValue)
167
+ checkHasContent(newValue)
168
+
169
+ // 延迟重置标志,防止循环更新
170
+ setTimeout(() => {
171
+ isInternalUpdate.value = false
172
+ }, 0)
173
+ }
174
+
175
+ // 检查是否有内容
176
+ const checkHasContent = (value?: string): void => {
177
+ const contentValue = value || generateValue()
178
+ const newHasContent = contentValue.trim().length > 0
179
+
180
+ if (hasContent.value !== newHasContent) {
181
+ hasContent.value = newHasContent
182
+ emit('content-status', newHasContent)
183
+ }
184
+ }
185
+
186
+ // 注册可编辑元素引用
187
+ const registerEditableRef = (el: HTMLSpanElement | null, index: number): void => {
188
+ if (el) {
189
+ // 保存引用
190
+ editableRefs.value[index] = el
191
+
192
+ // 设置初始内容 (只在初始时设置,后续由用户输入控制)
193
+ if (!el.textContent) {
194
+ el.textContent = editableParts.value[index].content
195
+ }
196
+
197
+ // 使用MutationObserver监听内容变化,但避免循环更新
198
+ const observer = new MutationObserver(() => {
199
+ if (activeFieldIndex.value === index && !isUserEditing.value) {
200
+ isUserEditing.value = true
201
+
202
+ // 延迟更新模型,避免与Vue渲染循环冲突
203
+ setTimeout(() => {
204
+ editableParts.value[index].content = el.textContent !== null ? el.textContent : ''
205
+ isUserEditing.value = false
206
+ }, 0)
207
+ }
208
+ })
209
+
210
+ observer.observe(el, {
211
+ characterData: true,
212
+ childList: true,
213
+ subtree: true,
214
+ })
215
+ }
216
+ }
217
+
218
+ // 处理内容输入事件
219
+ const handleContentInput = (event: Event, index: number): void => {
220
+ isUserEditing.value = true
221
+
222
+ // 获取当前输入内容
223
+ const target = event.target as HTMLElement
224
+ const content = target.textContent !== null ? target.textContent : ''
225
+
226
+ // 更新模型,但不触发DOM更新
227
+ if (editableParts.value[index].content !== content) {
228
+ editableParts.value[index].content = content
229
+ updateValue()
230
+ }
231
+
232
+ // 通过延时重置标志,防止与MutationObserver冲突
233
+ setTimeout(() => {
234
+ isUserEditing.value = false
235
+ }, 10)
236
+ }
237
+
238
+ // 将光标放到元素内容末尾
239
+ const placeCaretAtEnd = (el: HTMLElement): void => {
240
+ if (document.createRange) {
241
+ const range = document.createRange()
242
+ range.selectNodeContents(el)
243
+ // false表示光标放到末尾
244
+ range.collapse(false)
245
+
246
+ const selection = window.getSelection()
247
+ if (selection) {
248
+ selection.removeAllRanges()
249
+ selection.addRange(range)
250
+ }
251
+ }
84
252
  }
85
253
 
86
254
  // 激活输入块
87
255
  const activateField = (index: number): void => {
256
+ // 如果点击的就是当前激活的字段,不做任何处理
257
+ if (activeFieldIndex.value === index) {
258
+ return
259
+ }
260
+
261
+ // 如果当前已有激活的字段,先保存它的值
262
+ if (activeFieldIndex.value !== -1) {
263
+ const currentIndex = activeFieldIndex.value
264
+ const el = editableRefs.value[currentIndex]
265
+ if (el) {
266
+ editableParts.value[currentIndex].content = el.textContent !== null ? el.textContent : ''
267
+ updateValue()
268
+ }
269
+ }
270
+
271
+ // 设置激活状态
88
272
  activeFieldIndex.value = index
273
+ emit('field-active', true, index)
89
274
 
90
275
  // 确保DOM更新后再聚焦
91
276
  nextTick(() => {
92
- if (inputRefs.value[index]) {
93
- inputRefs.value[index]?.focus()
277
+ const el = editableRefs.value[index]
278
+ if (el) {
279
+ // 先获取焦点
280
+ el.focus()
281
+
282
+ // 确保元素有内容以便放置光标
283
+ if (!el.textContent && editableParts.value[index].content) {
284
+ el.textContent = editableParts.value[index].content
285
+ }
286
+
287
+ // 将光标放到末尾
288
+ placeCaretAtEnd(el)
94
289
  }
95
290
  })
96
291
  }
97
292
 
98
293
  // 取消激活输入块
99
294
  const deactivateField = (): void => {
295
+ const currentIndex = activeFieldIndex.value
296
+ if (currentIndex >= 0) {
297
+ // 更新当前编辑的内容
298
+ const el = editableRefs.value[currentIndex]
299
+ if (el) {
300
+ // 使用实际内容,不回退到占位符
301
+ const content = el.textContent !== null ? el.textContent : ''
302
+ editableParts.value[currentIndex].content = content
303
+ }
304
+
305
+ emit('field-active', false, currentIndex)
306
+ }
307
+
100
308
  updateValue()
101
309
  activeFieldIndex.value = -1
102
310
  }
103
311
 
104
312
  // 处理输入框键盘事件
105
- const handleInputKeyDown = (event: KeyboardEvent, index: number): void => {
106
- if (event.key === 'Tab') {
107
- event.preventDefault()
108
-
109
- // 找到下一个输入块
110
- const nextFieldIndex = findNextFieldIndex(index, event.shiftKey)
111
- if (nextFieldIndex !== -1) {
112
- // 先更新当前值
113
- updateValue()
114
- // 再激活下一个字段
115
- activateField(nextFieldIndex)
116
- }
117
- } else if (event.key === 'Enter') {
313
+ const handleInputKeyDown = (event: KeyboardEvent): void => {
314
+ // 只处理Enter键
315
+ if (event.key === 'Enter') {
118
316
  event.preventDefault()
119
317
  deactivateField()
120
318
  }
121
319
  }
122
320
 
123
- // 寻找下一个输入块索引,支持通过 shift+tab 反向查找
124
- const findNextFieldIndex = (currentIndex: number, isReverse = false): number => {
125
- if (isReverse) {
126
- // 向前查找(Shift+Tab)
127
- for (let i = currentIndex - 1; i >= 0; i--) {
128
- if (templateParts.value[i].isField) {
129
- return i
130
- }
131
- }
132
-
133
- // 如果没有找到,则循环到最后一个字段
134
- for (let i = templateParts.value.length - 1; i > currentIndex; i--) {
135
- if (templateParts.value[i].isField) {
136
- return i
137
- }
138
- }
139
- } else {
140
- // 向后查找(Tab)
141
- for (let i = currentIndex + 1; i < templateParts.value.length; i++) {
142
- if (templateParts.value[i].isField) {
143
- return i
144
- }
145
- }
146
-
147
- // 循环回到第一个输入块
148
- for (let i = 0; i < currentIndex; i++) {
149
- if (templateParts.value[i].isField) {
150
- return i
151
- }
152
- }
153
- }
154
-
155
- return -1
156
- }
157
-
158
321
  // 监听值变化
159
322
  watch(
160
323
  () => props.value,
161
324
  (newValue) => {
162
- // 如果外部值为空字符串,清空所有字段内容
325
+ // 如果外部值为空字符串,重置为默认placeholder值
163
326
  if (newValue === '') {
164
- resetFields()
327
+ resetToDefaultValues()
328
+ } else if (newValue && !isInternalUpdate.value) {
329
+ // 如果新值不为空,并且不是内部更新触发的,更新各部分内容
330
+ updatePartsFromValue(newValue)
165
331
  }
166
332
  },
167
333
  )
168
334
 
169
- // 重置所有字段内容
170
- const resetFields = (): void => {
171
- // 清空所有输入块内容
172
- templateParts.value.forEach((part) => {
335
+ // 监听模板变化
336
+ watch(
337
+ () => props.template,
338
+ () => {
339
+ // 当模板变化时,重新初始化
340
+ initializeEditableParts()
341
+ // 检查内容状态
342
+ nextTick(() => {
343
+ checkHasContent()
344
+ })
345
+ },
346
+ { immediate: true },
347
+ )
348
+
349
+ // 重置所有字段内容为默认值
350
+ const resetToDefaultValues = (): void => {
351
+ editableParts.value.forEach((part) => {
173
352
  if (part.isField) {
174
- part.content = ''
353
+ part.content = part.placeholder || ''
175
354
  }
176
355
  })
177
356
  // 更新值
178
357
  updateValue()
179
358
  }
180
359
 
360
+ // 重置所有字段内容
361
+ const resetFields = (): void => {
362
+ resetToDefaultValues()
363
+ }
364
+
365
+ // 组件挂载时
366
+ onMounted(() => {
367
+ // 初始化内容状态
368
+ checkHasContent()
369
+ })
370
+
181
371
  // 导出方法供父组件调用
182
372
  defineExpose<TemplateEditorExpose>({
183
373
  activateFirstField: () => {
184
- for (let i = 0; i < templateParts.value.length; i++) {
185
- if (templateParts.value[i].isField) {
374
+ for (let i = 0; i < editableParts.value.length; i++) {
375
+ if (editableParts.value[i].isField) {
186
376
  activateField(i)
187
377
  break
188
378
  }
@@ -195,7 +385,7 @@ defineExpose<TemplateEditorExpose>({
195
385
  <template>
196
386
  <div class="template-editor">
197
387
  <div class="template-content" ref="editorRef">
198
- <template v-for="(part, index) in templateParts" :key="index">
388
+ <template v-for="(part, index) in editableParts" :key="index">
199
389
  <!-- 普通文本部分 -->
200
390
  <span v-if="!part.isField">{{ part.content }}</span>
201
391
 
@@ -206,23 +396,26 @@ defineExpose<TemplateEditorExpose>({
206
396
  :class="{ 'template-field-active': activeFieldIndex === index }"
207
397
  @click="activateField(index)"
208
398
  >
209
- <input
399
+ <!-- 编辑状态显示 -->
400
+ <span
210
401
  v-if="activeFieldIndex === index"
211
- :ref="(el) => (inputRefs[index] = el)"
212
- v-model="part.content"
213
- class="template-input"
402
+ :ref="(el) => registerEditableRef(el as HTMLSpanElement, index)"
403
+ class="template-editable"
404
+ contenteditable="true"
405
+ @input="handleContentInput($event, index)"
214
406
  @blur="deactivateField()"
215
- @keydown="handleInputKeyDown($event, index)"
407
+ @keydown="handleInputKeyDown($event)"
216
408
  @click.stop
217
- />
218
- <span v-else class="template-placeholder">{{ part.content || part.placeholder }}</span>
409
+ ></span>
410
+ <!-- 非编辑状态显示 -->
411
+ <span v-else class="template-placeholder">{{ part.content }}</span>
219
412
  </span>
220
413
  </template>
221
414
  </div>
222
415
  </div>
223
416
  </template>
224
417
 
225
- <style scoped>
418
+ <style lang="less" scoped>
226
419
  .template-editor {
227
420
  width: 100%;
228
421
  min-height: 26px;
@@ -245,30 +438,28 @@ defineExpose<TemplateEditorExpose>({
245
438
  vertical-align: middle;
246
439
  cursor: text;
247
440
  transition: all 0.2s ease;
248
- }
249
441
 
250
- .template-field:hover {
251
- background: rgba(0, 0, 0, 0.08);
252
- }
442
+ &-active {
443
+ background-color: #ffffff;
444
+ border: 1px solid rgba(194, 194, 194);
445
+ border-radius: 4px;
446
+ }
253
447
 
254
- .template-placeholder {
255
- color: #666;
256
- user-select: none;
448
+ .template-placeholder {
449
+ color: #333;
450
+ user-select: none;
451
+ }
257
452
  }
258
453
 
259
- .template-input {
260
- box-sizing: border-box;
261
- width: 100%;
262
- height: 26px;
263
- border: 1px solid rgb(194, 194, 194);
264
- border-radius: 4px;
265
- padding: 0 10px;
454
+ .template-editable {
455
+ display: inline-block;
456
+ min-width: 1px; // 防止编辑框过窄
266
457
  outline: none;
267
- background: white;
268
- }
458
+ white-space: nowrap;
459
+ color: #333;
269
460
 
270
- .template-field-active {
271
- background: transparent;
272
- padding: 0;
461
+ &:focus {
462
+ outline: none;
463
+ }
273
464
  }
274
465
  </style>
@@ -1,10 +0,0 @@
1
- import { BubbleProps } from '../../index.type';
2
- type __VLS_Props = {
3
- bubbleItem: BubbleProps;
4
- };
5
- declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
6
- click: (...args: any[]) => void;
7
- }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
8
- onClick?: ((...args: any[]) => any) | undefined;
9
- }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLButtonElement>;
10
- export default _default;
@@ -1,2 +0,0 @@
1
- export { default as CopyAction } from './copy.vue';
2
- export { default as RefreshAction } from './refresh.vue';
@@ -1,2 +0,0 @@
1
- declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, HTMLButtonElement>;
2
- export default _default;
@@ -1,4 +0,0 @@
1
- import { Ref } from 'vue';
2
- export declare const useElementScroll: (elemRef: Ref<HTMLElement | null | undefined>) => {
3
- scrollToBottom: () => void;
4
- };
@@ -1,7 +0,0 @@
1
- import o from "./bubble-list.vue2.js";
2
- /* empty css */
3
- import t from "../../../../_virtual/_plugin-vue_export-helper.js";
4
- const s = /* @__PURE__ */ t(o, [["__scopeId", "data-v-5d3d74c8"]]);
5
- export {
6
- s as default
7
- };
@@ -1,37 +0,0 @@
1
- import { defineComponent as i, ref as p, computed as b, watch as d, createElementBlock as n, openBlock as r, Fragment as _, renderList as B, createBlock as g, mergeProps as C } from "vue";
2
- import k from "./bubble.vue.js";
3
- import { useElementScroll as h } from "./useScroll.js";
4
- const x = /* @__PURE__ */ i({
5
- __name: "bubble-list",
6
- props: {
7
- items: {},
8
- roles: {},
9
- autoScroll: { type: Boolean }
10
- },
11
- setup(s) {
12
- const t = s, l = p(), { scrollToBottom: c } = h(l), u = b(() => t.items.at(-1));
13
- d([() => t.items.length, () => {
14
- var e;
15
- return (e = u.value) == null ? void 0 : e.content;
16
- }], () => {
17
- t.autoScroll && c();
18
- });
19
- const a = (e) => {
20
- var o;
21
- return { ...e.role ? ((o = t.roles) == null ? void 0 : o[e.role]) || {} : {}, ...e };
22
- };
23
- return (e, m) => (r(), n("div", {
24
- class: "tr-bubble-list",
25
- ref_key: "scrollContainer",
26
- ref: l
27
- }, [
28
- (r(!0), n(_, null, B(t.items, (o, f) => (r(), g(k, C({
29
- key: o.id || f,
30
- ref_for: !0
31
- }, a(o)), null, 16))), 128))
32
- ], 512));
33
- }
34
- });
35
- export {
36
- x as default
37
- };
@@ -1,7 +0,0 @@
1
- import o from "./bubble.vue2.js";
2
- /* empty css */
3
- import t from "../../../../_virtual/_plugin-vue_export-helper.js";
4
- const e = /* @__PURE__ */ t(o, [["__scopeId", "data-v-f7db2e1c"]]);
5
- export {
6
- e as default
7
- };