@opentiny/tiny-robot 0.2.0-alpha.0 → 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 (164) hide show
  1. package/dist/action-group/ActionGroup.vue.d.ts +26 -0
  2. package/dist/action-group/ActionGroupItem.vue.d.ts +18 -0
  3. package/dist/action-group/index.d.ts +12 -0
  4. package/dist/action-group/index.type.d.ts +17 -0
  5. package/dist/bubble/index.d.ts +2 -2
  6. package/dist/bubble/index.type.d.ts +16 -18
  7. package/dist/feedback/components/SourceList.vue.d.ts +11 -0
  8. package/dist/feedback/components/index.d.ts +1 -0
  9. package/dist/feedback/index.d.ts +7 -0
  10. package/dist/feedback/index.type.d.ts +25 -0
  11. package/dist/feedback/index.vue.d.ts +13 -0
  12. package/dist/history/components/index.d.ts +2 -0
  13. package/dist/history/components/item-tag.vue.d.ts +5 -0
  14. package/dist/history/components/search-empty.vue.d.ts +7 -0
  15. package/dist/history/composables/index.d.ts +1 -0
  16. package/dist/history/composables/useEditItemTitle.d.ts +12 -0
  17. package/dist/history/index.d.ts +6 -0
  18. package/dist/history/index.type.d.ts +43 -0
  19. package/dist/history/index.vue.d.ts +2 -0
  20. package/dist/icon-button/index.d.ts +7 -0
  21. package/dist/icon-button/index.type.d.ts +6 -0
  22. package/dist/icon-button/index.vue.d.ts +6 -0
  23. package/dist/index.d.ts +10 -1
  24. package/dist/index.js +57 -27
  25. package/dist/node_modules/.pnpm/@opentiny_utils@3.22.0/node_modules/@opentiny/utils/dist/index.es.js +1335 -884
  26. package/dist/node_modules/.pnpm/@opentiny_vue-common@3.22.0/node_modules/@opentiny/vue-common/lib/index.js +660 -144
  27. package/dist/node_modules/.pnpm/@opentiny_vue-hooks@3.22.0/node_modules/@opentiny/vue-hooks/dist/src/vue-popper.js +85 -0
  28. package/dist/node_modules/.pnpm/@opentiny_vue-locale@3.22.0/node_modules/@opentiny/vue-locale/lib/index.js +1783 -0
  29. package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/tooltip/index.js +77 -0
  30. package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/tooltip/vue.js +90 -0
  31. package/dist/node_modules/.pnpm/@opentiny_vue-tooltip@3.22.0/node_modules/@opentiny/vue-tooltip/lib/index.js +176 -0
  32. package/dist/node_modules/.pnpm/@opentiny_vue-tooltip@3.22.0/node_modules/@opentiny/vue-tooltip/lib/pc.js +248 -0
  33. package/dist/node_modules/.pnpm/@vueuse_core@13.1.0_vue@3.5.13/node_modules/@vueuse/core/index.js +310 -0
  34. package/dist/node_modules/.pnpm/@vueuse_shared@13.1.0_vue@3.5.13/node_modules/@vueuse/shared/index.js +110 -0
  35. package/dist/packages/components/src/action-group/ActionGroup.vue.js +7 -0
  36. package/dist/packages/components/src/action-group/ActionGroup.vue2.js +121 -0
  37. package/dist/packages/components/src/action-group/ActionGroupItem.vue.js +14 -0
  38. package/dist/packages/components/src/action-group/ActionGroupItem.vue2.js +4 -0
  39. package/dist/packages/components/src/action-group/index.js +17 -0
  40. package/dist/packages/components/src/bubble/Bubble.vue.js +7 -0
  41. package/dist/packages/components/src/bubble/Bubble.vue2.js +76 -0
  42. package/dist/packages/components/src/bubble/BubbleList.vue.js +7 -0
  43. package/dist/packages/components/src/bubble/BubbleList.vue2.js +50 -0
  44. package/dist/packages/components/src/bubble/index.js +2 -2
  45. package/dist/packages/components/src/container/index.vue.js +2 -2
  46. package/dist/packages/components/src/container/index.vue2.js +36 -36
  47. package/dist/packages/components/src/feedback/components/SourceList.vue.js +7 -0
  48. package/dist/packages/components/src/feedback/components/SourceList.vue2.js +52 -0
  49. package/dist/packages/components/src/feedback/index.js +9 -0
  50. package/dist/packages/components/src/feedback/index.vue.js +7 -0
  51. package/dist/packages/components/src/feedback/index.vue2.js +143 -0
  52. package/dist/packages/components/src/history/components/item-tag.vue.js +7 -0
  53. package/dist/packages/components/src/history/components/item-tag.vue2.js +21 -0
  54. package/dist/packages/components/src/history/components/search-empty.vue.js +7 -0
  55. package/dist/packages/components/src/history/components/search-empty.vue2.js +20 -0
  56. package/dist/packages/components/src/history/composables/useEditItemTitle.js +43 -0
  57. package/dist/packages/components/src/history/index.js +11 -0
  58. package/dist/packages/components/src/history/index.vue.js +7 -0
  59. package/dist/packages/components/src/history/index.vue2.js +130 -0
  60. package/dist/packages/components/src/icon-button/index.js +9 -0
  61. package/dist/packages/components/src/icon-button/index.vue.js +7 -0
  62. package/dist/packages/components/src/icon-button/index.vue2.js +22 -0
  63. package/dist/packages/components/src/prompts/prompt.vue.js +2 -2
  64. package/dist/packages/components/src/prompts/prompt.vue2.js +17 -15
  65. package/dist/packages/components/src/question/components/HotQuestions.vue.js +23 -23
  66. package/dist/packages/components/src/question/index.vue.js +18 -18
  67. package/dist/packages/components/src/sender/components/TemplateEditor.vue.js +7 -0
  68. package/dist/packages/components/src/sender/components/TemplateEditor.vue2.js +175 -0
  69. package/dist/packages/components/src/sender/index.vue.js +149 -128
  70. package/dist/packages/components/src/suggestion/components/CategoryNav.vue.js +38 -0
  71. package/dist/packages/components/src/suggestion/components/CategoryNav.vue2.js +4 -0
  72. package/dist/packages/components/src/suggestion/components/SuggestionCapsule.vue.js +107 -0
  73. package/dist/packages/components/src/suggestion/components/SuggestionCapsule.vue2.js +4 -0
  74. package/dist/packages/components/src/suggestion/components/SuggestionPanel.vue.js +123 -0
  75. package/dist/packages/components/src/suggestion/components/SuggestionPanel.vue2.js +4 -0
  76. package/dist/packages/components/src/suggestion/composables/useKeyboardNavigation.js +45 -0
  77. package/dist/packages/components/src/suggestion/composables/useTriggerDetection.js +17 -0
  78. package/dist/packages/components/src/suggestion/index.js +9 -0
  79. package/dist/packages/components/src/suggestion/index.vue.js +179 -0
  80. package/dist/packages/components/src/suggestion/index.vue2.js +4 -0
  81. package/dist/packages/components/src/suggestion/utils/dom.js +18 -0
  82. package/dist/packages/svgs/dist/tiny-robot-svgs.js +306 -90
  83. package/dist/question/components/HotQuestions.vue.d.ts +2 -2
  84. package/dist/sender/components/TemplateEditor.vue.d.ts +18 -0
  85. package/dist/sender/index.type.d.ts +47 -0
  86. package/dist/sender/index.vue.d.ts +70 -5
  87. package/dist/style.css +1 -1
  88. package/dist/suggestion/components/CategoryNav.vue.d.ts +45 -0
  89. package/dist/suggestion/components/SuggestionCapsule.vue.d.ts +32 -0
  90. package/dist/suggestion/components/SuggestionPanel.vue.d.ts +84 -0
  91. package/dist/suggestion/composables/useKeyboardNavigation.d.ts +18 -0
  92. package/dist/suggestion/composables/useSuggestionFilter.d.ts +10 -0
  93. package/dist/suggestion/composables/useTriggerDetection.d.ts +11 -0
  94. package/dist/suggestion/index.d.ts +7 -0
  95. package/dist/suggestion/index.type.d.ts +94 -0
  96. package/dist/suggestion/index.vue.d.ts +343 -0
  97. package/dist/suggestion/utils/dom.d.ts +20 -0
  98. package/package.json +4 -3
  99. package/src/action-group/ActionGroup.vue +247 -0
  100. package/src/action-group/ActionGroupItem.vue +9 -0
  101. package/src/action-group/index.ts +25 -0
  102. package/src/action-group/index.type.ts +21 -0
  103. package/src/bubble/Bubble.vue +153 -0
  104. package/src/bubble/BubbleList.vue +55 -0
  105. package/src/bubble/index.ts +2 -2
  106. package/src/bubble/index.type.ts +7 -21
  107. package/src/container/index.vue +10 -36
  108. package/src/feedback/components/SourceList.vue +112 -0
  109. package/src/feedback/components/index.ts +1 -0
  110. package/src/feedback/index.ts +12 -0
  111. package/src/feedback/index.type.ts +27 -0
  112. package/src/feedback/index.vue +166 -0
  113. package/src/history/components/index.ts +2 -0
  114. package/src/history/components/item-tag.vue +49 -0
  115. package/src/history/components/search-empty.vue +38 -0
  116. package/src/history/composables/index.ts +1 -0
  117. package/src/history/composables/useEditItemTitle.ts +75 -0
  118. package/src/history/index.ts +12 -0
  119. package/src/history/index.type.ts +50 -0
  120. package/src/history/index.vue +292 -0
  121. package/src/icon-button/index.ts +12 -0
  122. package/src/icon-button/index.type.ts +7 -0
  123. package/src/icon-button/index.vue +58 -0
  124. package/src/index.ts +33 -1
  125. package/src/prompts/prompt.vue +7 -21
  126. package/src/question/components/HotQuestions.vue +1 -1
  127. package/src/question/index.less +9 -10
  128. package/src/sender/components/TemplateEditor.vue +465 -0
  129. package/src/sender/index.less +17 -7
  130. package/src/sender/index.type.ts +51 -0
  131. package/src/sender/index.vue +56 -8
  132. package/src/sender/vars.less +3 -3
  133. package/src/suggestion/components/CategoryNav.vue +38 -0
  134. package/src/suggestion/components/SuggestionCapsule.vue +183 -0
  135. package/src/suggestion/components/SuggestionPanel.vue +147 -0
  136. package/src/suggestion/composables/useKeyboardNavigation.ts +101 -0
  137. package/src/suggestion/composables/useSuggestionFilter.ts +34 -0
  138. package/src/suggestion/composables/useTriggerDetection.ts +46 -0
  139. package/src/suggestion/index.less +497 -0
  140. package/src/suggestion/index.ts +12 -0
  141. package/src/suggestion/index.type.ts +101 -0
  142. package/src/suggestion/index.vue +338 -0
  143. package/src/suggestion/utils/dom.ts +66 -0
  144. package/src/suggestion/vars.less +141 -0
  145. package/dist/bubble/components/actions/copy.vue.d.ts +0 -10
  146. package/dist/bubble/components/actions/index.d.ts +0 -2
  147. package/dist/bubble/components/actions/refresh.vue.d.ts +0 -2
  148. package/dist/bubble/useScroll.d.ts +0 -4
  149. package/dist/packages/components/src/bubble/bubble-list.vue.js +0 -7
  150. package/dist/packages/components/src/bubble/bubble-list.vue2.js +0 -37
  151. package/dist/packages/components/src/bubble/bubble.vue.js +0 -7
  152. package/dist/packages/components/src/bubble/bubble.vue2.js +0 -118
  153. package/dist/packages/components/src/bubble/components/actions/copy.vue.js +0 -7
  154. package/dist/packages/components/src/bubble/components/actions/copy.vue2.js +0 -35
  155. package/dist/packages/components/src/bubble/components/actions/refresh.vue.js +0 -7
  156. package/dist/packages/components/src/bubble/components/actions/refresh.vue2.js +0 -16
  157. package/dist/packages/components/src/bubble/useScroll.js +0 -13
  158. package/src/bubble/bubble-list.vue +0 -42
  159. package/src/bubble/bubble.vue +0 -247
  160. package/src/bubble/components/actions/copy.vue +0 -54
  161. package/src/bubble/components/actions/index.ts +0 -2
  162. package/src/bubble/components/actions/refresh.vue +0 -31
  163. package/src/bubble/useScroll.ts +0 -14
  164. /package/dist/bubble/{bubble-list.vue.d.ts → BubbleList.vue.d.ts} +0 -0
@@ -0,0 +1,292 @@
1
+ <script lang="ts" setup>
2
+ import { IconClose, IconDelete, IconEditPen, IconSearch } from '@opentiny/tiny-robot-svgs'
3
+ import { TinyButton, TinyInput } from '@opentiny/vue'
4
+ import { computed } from 'vue'
5
+ import { ItemTag, SearchEmpty } from './components'
6
+ import { useEditItemTitle } from './composables'
7
+ import type {
8
+ HistoryEvents,
9
+ HistoryGroup,
10
+ HistoryItem,
11
+ HistoryProps,
12
+ MultiTabHistoryProps,
13
+ SingleTabHistoryProps,
14
+ } from './index.type'
15
+
16
+ const props = withDefaults(defineProps<HistoryProps>(), {
17
+ searchFn: (query: string, { title }: HistoryItem) => {
18
+ if (!query) {
19
+ return true
20
+ }
21
+
22
+ return title.toLowerCase().includes(query.toLowerCase())
23
+ },
24
+ })
25
+
26
+ const activeTab = defineModel<HistoryProps['activeTab']>('activeTab')
27
+ const searchQuery = defineModel<HistoryProps['searchQuery']>('searchQuery')
28
+
29
+ const emit = defineEmits<HistoryEvents>()
30
+
31
+ const computedTabs = computed(() => {
32
+ if (Array.isArray((props as MultiTabHistoryProps).tabs)) {
33
+ return (props as MultiTabHistoryProps).tabs
34
+ }
35
+
36
+ return [{ title: (props as SingleTabHistoryProps).tabTitle, id: '0' }]
37
+ })
38
+
39
+ const computedActiveTab = computed(() => {
40
+ return activeTab.value || computedTabs.value[0].id
41
+ })
42
+
43
+ const enableTabBottomBorder = computed(() => {
44
+ return computedTabs.value.length > 1
45
+ })
46
+
47
+ const groups = computed(() => {
48
+ if (Array.isArray(props.data)) {
49
+ return props.data || []
50
+ }
51
+
52
+ return props.data[computedActiveTab.value] || []
53
+ })
54
+
55
+ const filteredGroups = computed(() => {
56
+ if (!props.searchBar) {
57
+ return groups.value
58
+ }
59
+
60
+ const groupsWithFilteredItems = groups.value.map((group) => {
61
+ return {
62
+ ...group,
63
+ items: group.items.filter((item) => props.searchFn(searchQuery.value || '', item)),
64
+ } as HistoryGroup
65
+ })
66
+
67
+ return groupsWithFilteredItems.filter((group) => group.items.length > 0)
68
+ })
69
+
70
+ const handleItemClick = (item: HistoryItem) => {
71
+ if (item.id === editingItem.value?.id) {
72
+ return
73
+ }
74
+
75
+ emit('item-click', item)
76
+ }
77
+
78
+ const handleClose = () => {
79
+ emit('close')
80
+ }
81
+
82
+ const handleDelete = (item: HistoryItem) => {
83
+ // TODO 删除确认弹窗
84
+ emit('item-delete', item)
85
+ }
86
+
87
+ const { editingItem, handleEdit, handleEditorInputRef, handleKeyDown } = useEditItemTitle(emit)
88
+ </script>
89
+
90
+ <template>
91
+ <div class="tr-history">
92
+ <div class="tr-history__tabs">
93
+ <div
94
+ v-for="tab in computedTabs"
95
+ :key="tab.id"
96
+ :class="['tr-history__tab', { active: computedActiveTab === tab.id }]"
97
+ @click="activeTab = tab.id"
98
+ >
99
+ {{ tab.title }}
100
+ </div>
101
+ </div>
102
+ <div v-if="props.searchBar" class="tr-history__search">
103
+ <tiny-input
104
+ v-model="searchQuery"
105
+ :placeholder="props.searchPlaceholder || '搜索对话名称'"
106
+ :prefix-icon="IconSearch"
107
+ clearable
108
+ />
109
+ </div>
110
+ <div class="tr-history__content">
111
+ <template v-if="filteredGroups.length > 0">
112
+ <div v-for="group in filteredGroups" :key="group.date" class="tr-history__group">
113
+ <div class="tr-history__date">
114
+ <span>{{ group.date }}</span>
115
+ </div>
116
+ <div
117
+ v-for="item in group.items"
118
+ :key="`${item.id}-${item.title}`"
119
+ :class="['tr-history__item', { selected: props.selected === item.id }]"
120
+ @click="handleItemClick(item)"
121
+ >
122
+ <template v-if="editingItem?.id !== item.id">
123
+ <span class="tr-history__item-title">{{ item.title }}</span>
124
+ <ItemTag v-if="item.tag" class="tr-history__item-tag" v-bind="item.tag" />
125
+ <div class="tr-history__item-actions">
126
+ <!-- TODO add popover提示 -->
127
+ <tiny-button :icon="IconEditPen" type="text" size="mini" @click.stop="handleEdit(item)" />
128
+ <tiny-button :icon="IconDelete" type="text" size="mini" @click.stop="handleDelete(item)" />
129
+ </div>
130
+ </template>
131
+ <template v-else>
132
+ <input
133
+ v-model="editingItem.title"
134
+ class="tr-history__item-edit"
135
+ :ref="handleEditorInputRef"
136
+ v-on:keydown="handleKeyDown"
137
+ />
138
+ </template>
139
+ </div>
140
+ </div>
141
+ </template>
142
+ <SearchEmpty v-else :text="searchQuery ? '暂无搜索结果' : '暂无内容'" />
143
+ </div>
144
+ <div class="tr-history__close">
145
+ <tiny-button :icon="IconClose" type="text" size="mini" @click="handleClose" />
146
+ </div>
147
+ </div>
148
+ </template>
149
+
150
+ <style lang="less" scoped>
151
+ .tr-history {
152
+ display: flex;
153
+ gap: 16px;
154
+ flex-direction: column;
155
+ background: #fff;
156
+ border-radius: 24px;
157
+ padding: 0 20px;
158
+ position: relative;
159
+ color: rgb(25, 25, 25);
160
+
161
+ .tr-history__tabs {
162
+ flex-shrink: 0;
163
+ display: flex;
164
+ padding-top: 24px;
165
+ gap: 32px;
166
+ font-size: 16px;
167
+ line-height: 1.5;
168
+ border-bottom: v-bind("enableTabBottomBorder ? '1px solid rgb(240, 240, 240)': 'none'");
169
+
170
+ .tr-history__tab {
171
+ cursor: pointer;
172
+ padding-bottom: 8px;
173
+
174
+ &.active {
175
+ font-weight: 600;
176
+ border-bottom: v-bind("enableTabBottomBorder ? '2px solid rgb(25, 25, 25)': 'none'");
177
+ }
178
+ }
179
+ }
180
+
181
+ .tr-history__close {
182
+ position: absolute;
183
+ right: 16px;
184
+ top: 16px;
185
+ }
186
+
187
+ .tr-history__search {
188
+ flex-shrink: 0;
189
+
190
+ :deep(.tiny-input__inner) {
191
+ border-radius: 999px;
192
+ }
193
+ }
194
+
195
+ .tr-history__content {
196
+ flex: 1;
197
+ display: flex;
198
+ flex-direction: column;
199
+ gap: 12px;
200
+ overflow-y: auto;
201
+ padding: 0 20px;
202
+ margin: 0 -20px;
203
+ margin-bottom: 12px;
204
+
205
+ .tr-history__date {
206
+ font-size: 12px;
207
+ line-height: 20px;
208
+ padding: 4px 12px;
209
+ color: rgb(128, 128, 128);
210
+ background-color: rgb(255, 255, 255);
211
+ position: sticky;
212
+ top: 0;
213
+ z-index: 10;
214
+ }
215
+
216
+ .tr-history__item {
217
+ --tr-history-item-bg: rgb(255, 255, 255);
218
+
219
+ display: flex;
220
+ align-items: center;
221
+ font-size: 14px;
222
+ line-height: 24px;
223
+ border-radius: 12px;
224
+ background-color: var(--tr-history-item-bg);
225
+ cursor: pointer;
226
+ position: relative;
227
+ z-index: 1;
228
+ transition: box-shadow 0.3s ease;
229
+
230
+ &:hover {
231
+ box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.08);
232
+ z-index: 20;
233
+
234
+ .tr-history__item-actions {
235
+ opacity: 1;
236
+ }
237
+ }
238
+
239
+ &.selected {
240
+ --tr-history-item-bg: rgb(222, 236, 255);
241
+ }
242
+
243
+ .tr-history__item-title {
244
+ padding: 10px 12px;
245
+ font-size: 14px;
246
+ overflow: hidden;
247
+ text-overflow: ellipsis;
248
+ white-space: nowrap;
249
+ }
250
+
251
+ .tr-history__item-tag {
252
+ flex-shrink: 0;
253
+ margin-right: 12px;
254
+ }
255
+
256
+ .tr-history__item-actions {
257
+ display: flex;
258
+ gap: 8px;
259
+ opacity: 0;
260
+ position: absolute;
261
+ right: 12px;
262
+ background-color: var(--tr-history-item-bg);
263
+
264
+ &::before {
265
+ content: '';
266
+ position: absolute;
267
+ right: 100%;
268
+ width: 40px;
269
+ height: 100%;
270
+
271
+ background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, var(--tr-history-item-bg) 100%);
272
+ }
273
+ }
274
+
275
+ .tr-history__item-edit {
276
+ width: 100%;
277
+ font-size: 14px;
278
+ height: 44px;
279
+ border-radius: 12px;
280
+ border: 1px solid rgb(20, 118, 255);
281
+ padding: 0 12px;
282
+ }
283
+ }
284
+ }
285
+
286
+ .tiny-button {
287
+ --tv-Button-height: 20px;
288
+ --tv-Button-border-radius-only-icon-ontext: 999px;
289
+ margin: 0;
290
+ }
291
+ }
292
+ </style>
@@ -0,0 +1,12 @@
1
+ import { App } from 'vue'
2
+ import IconButton from './index.vue'
3
+
4
+ IconButton.name = 'TrIconButton'
5
+
6
+ const install = function <T>(app: App<T>) {
7
+ app.component(IconButton.name!, IconButton)
8
+ }
9
+
10
+ IconButton.install = install
11
+
12
+ export default IconButton as typeof IconButton & { install: typeof install }
@@ -0,0 +1,7 @@
1
+ import { Component, VNode } from 'vue'
2
+
3
+ export interface IconButtonProps {
4
+ icon: VNode | Component
5
+ size?: string | number
6
+ svgSize?: string | number
7
+ }
@@ -0,0 +1,58 @@
1
+ <script setup lang="ts">
2
+ import { IconButtonProps } from './index.type'
3
+ import { computed } from 'vue'
4
+
5
+ const props = withDefaults(defineProps<IconButtonProps>(), {
6
+ size: '24px',
7
+ svgSize: '16px',
8
+ })
9
+
10
+ const formatSize = (size: string | number) => {
11
+ if (!isNaN(Number(size))) {
12
+ return `${size}px`
13
+ }
14
+
15
+ return size as string
16
+ }
17
+
18
+ const size = computed(() => formatSize(props.size))
19
+ const svgSize = computed(() => formatSize(props.svgSize))
20
+ </script>
21
+
22
+ <template>
23
+ <button class="tr-icon-button">
24
+ <component :is="props.icon" />
25
+ </button>
26
+ </template>
27
+ <style lang="less" scoped>
28
+ button.tr-icon-button {
29
+ --tr-icon-button-bg: transparent;
30
+ --tr-icon-button-hover-bg: rgba(0, 0, 0, 0.04);
31
+ --tr-icon-button-active-bg: rgba(0, 0, 0, 0.15);
32
+ --tr-icon-button-border-radius: 8px;
33
+
34
+ width: v-bind('size');
35
+ height: v-bind('size');
36
+ display: inline-flex;
37
+ align-items: center;
38
+ justify-content: center;
39
+ border: none;
40
+ border-radius: var(--tr-icon-button-border-radius);
41
+ cursor: pointer;
42
+ padding: 0;
43
+ transition: background-color 0.3s;
44
+ background-color: var(--tr-icon-button-bg);
45
+
46
+ &:hover {
47
+ background-color: var(--tr-icon-button-hover-bg);
48
+ }
49
+
50
+ &:active {
51
+ background-color: var(--tr-icon-button-active-bg);
52
+ }
53
+
54
+ svg {
55
+ font-size: v-bind('svgSize');
56
+ }
57
+ }
58
+ </style>
package/src/index.ts CHANGED
@@ -2,17 +2,40 @@ import { App } from 'vue'
2
2
  import { Bubble, BubbleList } from './bubble'
3
3
  import Container from './container'
4
4
  import Conversations from './conversations'
5
+ import Feedback from './feedback'
6
+ import History from './history'
7
+ import IconButton from './icon-button'
5
8
  import { Prompt, Prompts } from './prompts'
6
9
  import Question from './question'
7
10
  import Sender from './sender'
8
11
  import Welcome from './welcome'
12
+ import Suggestion from './suggestion'
9
13
 
10
14
  export * from './bubble/index.type'
15
+ export * from './container/index.type'
16
+ export * from './feedback/index.type'
17
+ export * from './history/index.type'
18
+ export * from './icon-button/index.type'
11
19
  export * from './prompts/index.type'
12
20
  export * from './sender/index.type'
13
21
  export * from './welcome/index.type'
22
+ export * from './suggestion/index.type'
14
23
 
15
- const components = [Bubble, BubbleList, Container, Conversations, Prompt, Prompts, Question, Sender, Welcome]
24
+ const components = [
25
+ Bubble,
26
+ BubbleList,
27
+ Container,
28
+ Conversations,
29
+ Feedback,
30
+ History,
31
+ IconButton,
32
+ Prompt,
33
+ Prompts,
34
+ Question,
35
+ Sender,
36
+ Welcome,
37
+ Suggestion,
38
+ ]
16
39
 
17
40
  export default {
18
41
  install<T>(app: App<T>) {
@@ -32,6 +55,12 @@ export {
32
55
  Container as TrContainer,
33
56
  Conversations,
34
57
  Conversations as TrConversations,
58
+ Feedback,
59
+ Feedback as TrFeedback,
60
+ History,
61
+ History as TrHistory,
62
+ IconButton,
63
+ IconButton as TrIconButton,
35
64
  Prompt,
36
65
  Prompt as TrPrompt,
37
66
  Prompts,
@@ -40,5 +69,8 @@ export {
40
69
  Sender as TrSender,
41
70
  Welcome,
42
71
  Welcome as TrWelcome,
72
+ Suggestion,
73
+ Suggestion as TrSuggestion,
43
74
  Question,
75
+ Question as TrQuestion,
44
76
  }
@@ -1,39 +1,25 @@
1
1
  <script setup lang="ts">
2
- import { computed, defineComponent, VNode } from 'vue'
3
2
  import { PromptProps } from './index.type'
4
3
 
5
4
  const props = defineProps<PromptProps>()
6
-
7
- const vnodeToComponent = (vnode?: VNode | string) => {
8
- if (!vnode) {
9
- return null
10
- }
11
-
12
- return defineComponent(() => {
13
- return () => vnode
14
- })
15
- }
16
-
17
- const iconComp = computed(() => {
18
- return vnodeToComponent(props.icon)
19
- })
20
-
21
- const badgeComp = computed(() => {
22
- return vnodeToComponent(props.badge)
23
- })
24
5
  </script>
25
6
 
26
7
  <template>
27
8
  <div :class="['tr-prompt', { disabled: props.disabled }]">
28
9
  <div class="tr-prompt__icon">
29
- <component :is="iconComp"></component>
10
+ <component :is="props.icon"></component>
30
11
  </div>
31
12
  <div class="tr-prompt__content">
32
13
  <h6 class="tr-prompt__content-label">{{ props.label }}</h6>
33
14
  <p v-if="props.description" class="tr-prompt__content-description">{{ props.description }}</p>
34
15
  </div>
35
16
  <div :class="['tr-prompt__badge', { label: typeof props.badge === 'string' }]">
36
- <component :is="badgeComp"></component>
17
+ <template v-if="typeof props.badge === 'string'">
18
+ {{ props.badge }}
19
+ </template>
20
+ <template v-else>
21
+ <component :is="props.badge"></component>
22
+ </template>
37
23
  </div>
38
24
  </div>
39
25
  </template>
@@ -91,7 +91,7 @@ const modalRef = ref<HTMLElement | null>(null)
91
91
  <div v-if="visible" class="tr-question-modal-backdrop" @mousedown="handleClickOutside">
92
92
  <div ref="modalRef" class="tr-question-panel" :style="{ width: modalWidth }" @mousedown.stop>
93
93
  <div class="tr-question-header">
94
- <div style="display: flex; align-items: center; gap: 12px">
94
+ <div style="display: flex; align-items: center; gap: 12px; font-size: 36px">
95
95
  <div><IconHotQuestion /></div>
96
96
  <div class="tr-question-header-title">热门问题</div>
97
97
  </div>
@@ -53,8 +53,7 @@ body.tr-modal-open {
53
53
 
54
54
  /* 按钮图标 */
55
55
  & > svg {
56
- width: 28px;
57
- height: 28px;
56
+ font-size: 28px;
58
57
  border-radius: 50%;
59
58
  fill: #ffffff;
60
59
  }
@@ -343,9 +342,8 @@ body.tr-modal-open {
343
342
  box-shadow: var(--tr-question-common-item-shadow);
344
343
  transition: var(--tr-question-hover-transition);
345
344
 
346
- & > svg {
347
- width: 16px;
348
- height: 16px;
345
+ & svg {
346
+ font-size: 16px;
349
347
  }
350
348
 
351
349
  /* 悬停效果 */
@@ -394,15 +392,16 @@ body.tr-modal-open {
394
392
 
395
393
  /* 按钮图标 */
396
394
  & > svg {
397
- width: 1em;
398
- height: 1em;
399
- font-size: 32px;
395
+ font-size: 20px;
396
+ background-color: #fff;
397
+ color: rgb(89, 89, 89);
398
+ box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.15);
400
399
  border-radius: 50%;
401
- fill: #ffffff;
400
+ transition: background-color 0.3s ease;
402
401
  }
403
402
 
404
403
  & > svg:hover {
405
- fill: #f5f5f5;
404
+ background-color: #f5f5f5;
406
405
  }
407
406
  }
408
407