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

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 (136) 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 +16 -0
  5. package/dist/feedback/components/SourceList.vue.d.ts +11 -0
  6. package/dist/feedback/components/index.d.ts +1 -0
  7. package/dist/feedback/index.d.ts +7 -0
  8. package/dist/feedback/index.type.d.ts +25 -0
  9. package/dist/feedback/index.vue.d.ts +13 -0
  10. package/dist/history/components/index.d.ts +2 -0
  11. package/dist/history/components/item-tag.vue.d.ts +5 -0
  12. package/dist/history/components/search-empty.vue.d.ts +7 -0
  13. package/dist/history/composables/index.d.ts +1 -0
  14. package/dist/history/composables/useEditItemTitle.d.ts +12 -0
  15. package/dist/history/index.d.ts +6 -0
  16. package/dist/history/index.type.d.ts +43 -0
  17. package/dist/history/index.vue.d.ts +2 -0
  18. package/dist/icon-button/index.d.ts +7 -0
  19. package/dist/icon-button/index.type.d.ts +7 -0
  20. package/dist/icon-button/index.vue.d.ts +6 -0
  21. package/dist/index.d.ts +10 -1
  22. package/dist/index.js +57 -27
  23. package/dist/node_modules/.pnpm/@opentiny_utils@3.22.0/node_modules/@opentiny/utils/dist/index.es.js +1335 -884
  24. package/dist/node_modules/.pnpm/@opentiny_vue-common@3.22.0/node_modules/@opentiny/vue-common/lib/index.js +660 -144
  25. package/dist/node_modules/.pnpm/@opentiny_vue-hooks@3.22.0/node_modules/@opentiny/vue-hooks/dist/src/vue-popper.js +85 -0
  26. package/dist/node_modules/.pnpm/@opentiny_vue-locale@3.22.0/node_modules/@opentiny/vue-locale/lib/index.js +1783 -0
  27. package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/tooltip/index.js +77 -0
  28. package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/tooltip/vue.js +90 -0
  29. package/dist/node_modules/.pnpm/@opentiny_vue-tooltip@3.22.0/node_modules/@opentiny/vue-tooltip/lib/index.js +176 -0
  30. package/dist/node_modules/.pnpm/@opentiny_vue-tooltip@3.22.0/node_modules/@opentiny/vue-tooltip/lib/pc.js +248 -0
  31. package/dist/node_modules/.pnpm/@vueuse_core@13.1.0_vue@3.5.13/node_modules/@vueuse/core/index.js +190 -0
  32. package/dist/node_modules/.pnpm/@vueuse_shared@13.1.0_vue@3.5.13/node_modules/@vueuse/shared/index.js +53 -0
  33. package/dist/packages/components/src/action-group/ActionGroup.vue.js +7 -0
  34. package/dist/packages/components/src/action-group/ActionGroup.vue2.js +97 -0
  35. package/dist/packages/components/src/action-group/ActionGroupItem.vue.js +14 -0
  36. package/dist/packages/components/src/action-group/ActionGroupItem.vue2.js +4 -0
  37. package/dist/packages/components/src/action-group/index.js +17 -0
  38. package/dist/packages/components/src/bubble/bubble.vue.js +2 -2
  39. package/dist/packages/components/src/bubble/bubble.vue2.js +46 -46
  40. package/dist/packages/components/src/container/index.vue.js +1 -1
  41. package/dist/packages/components/src/container/index.vue2.js +17 -17
  42. package/dist/packages/components/src/feedback/components/SourceList.vue.js +7 -0
  43. package/dist/packages/components/src/feedback/components/SourceList.vue2.js +52 -0
  44. package/dist/packages/components/src/feedback/index.js +9 -0
  45. package/dist/packages/components/src/feedback/index.vue.js +7 -0
  46. package/dist/packages/components/src/feedback/index.vue2.js +142 -0
  47. package/dist/packages/components/src/history/components/item-tag.vue.js +7 -0
  48. package/dist/packages/components/src/history/components/item-tag.vue2.js +21 -0
  49. package/dist/packages/components/src/history/components/search-empty.vue.js +7 -0
  50. package/dist/packages/components/src/history/components/search-empty.vue2.js +20 -0
  51. package/dist/packages/components/src/history/composables/useEditItemTitle.js +43 -0
  52. package/dist/packages/components/src/history/index.js +11 -0
  53. package/dist/packages/components/src/history/index.vue.js +7 -0
  54. package/dist/packages/components/src/history/index.vue2.js +130 -0
  55. package/dist/packages/components/src/icon-button/index.js +9 -0
  56. package/dist/packages/components/src/icon-button/index.vue.js +7 -0
  57. package/dist/packages/components/src/icon-button/index.vue2.js +40 -0
  58. package/dist/packages/components/src/prompts/prompt.vue.js +2 -2
  59. package/dist/packages/components/src/prompts/prompt.vue2.js +17 -15
  60. package/dist/packages/components/src/question/components/HotQuestions.vue.js +23 -23
  61. package/dist/packages/components/src/question/index.vue.js +18 -18
  62. package/dist/packages/components/src/sender/components/TemplateEditor.vue.js +7 -0
  63. package/dist/packages/components/src/sender/components/TemplateEditor.vue2.js +121 -0
  64. package/dist/packages/components/src/sender/index.vue.js +149 -128
  65. package/dist/packages/components/src/suggestion/components/CategoryNav.vue.js +38 -0
  66. package/dist/packages/components/src/suggestion/components/CategoryNav.vue2.js +4 -0
  67. package/dist/packages/components/src/suggestion/components/SuggestionCapsule.vue.js +107 -0
  68. package/dist/packages/components/src/suggestion/components/SuggestionCapsule.vue2.js +4 -0
  69. package/dist/packages/components/src/suggestion/components/SuggestionPanel.vue.js +123 -0
  70. package/dist/packages/components/src/suggestion/components/SuggestionPanel.vue2.js +4 -0
  71. package/dist/packages/components/src/suggestion/composables/useKeyboardNavigation.js +45 -0
  72. package/dist/packages/components/src/suggestion/composables/useTriggerDetection.js +17 -0
  73. package/dist/packages/components/src/suggestion/index.js +9 -0
  74. package/dist/packages/components/src/suggestion/index.vue.js +179 -0
  75. package/dist/packages/components/src/suggestion/index.vue2.js +4 -0
  76. package/dist/packages/components/src/suggestion/utils/dom.js +18 -0
  77. package/dist/packages/svgs/dist/tiny-robot-svgs.js +306 -90
  78. package/dist/question/components/HotQuestions.vue.d.ts +2 -2
  79. package/dist/sender/components/TemplateEditor.vue.d.ts +18 -0
  80. package/dist/sender/index.type.d.ts +47 -0
  81. package/dist/sender/index.vue.d.ts +68 -3
  82. package/dist/style.css +1 -1
  83. package/dist/suggestion/components/CategoryNav.vue.d.ts +45 -0
  84. package/dist/suggestion/components/SuggestionCapsule.vue.d.ts +32 -0
  85. package/dist/suggestion/components/SuggestionPanel.vue.d.ts +84 -0
  86. package/dist/suggestion/composables/useKeyboardNavigation.d.ts +18 -0
  87. package/dist/suggestion/composables/useSuggestionFilter.d.ts +10 -0
  88. package/dist/suggestion/composables/useTriggerDetection.d.ts +11 -0
  89. package/dist/suggestion/index.d.ts +7 -0
  90. package/dist/suggestion/index.type.d.ts +94 -0
  91. package/dist/suggestion/index.vue.d.ts +343 -0
  92. package/dist/suggestion/utils/dom.d.ts +20 -0
  93. package/package.json +4 -3
  94. package/src/action-group/ActionGroup.vue +232 -0
  95. package/src/action-group/ActionGroupItem.vue +9 -0
  96. package/src/action-group/index.ts +25 -0
  97. package/src/action-group/index.type.ts +20 -0
  98. package/src/bubble/bubble.vue +4 -14
  99. package/src/container/index.vue +1 -2
  100. package/src/feedback/components/SourceList.vue +112 -0
  101. package/src/feedback/components/index.ts +1 -0
  102. package/src/feedback/index.ts +12 -0
  103. package/src/feedback/index.type.ts +27 -0
  104. package/src/feedback/index.vue +166 -0
  105. package/src/history/components/index.ts +2 -0
  106. package/src/history/components/item-tag.vue +49 -0
  107. package/src/history/components/search-empty.vue +38 -0
  108. package/src/history/composables/index.ts +1 -0
  109. package/src/history/composables/useEditItemTitle.ts +75 -0
  110. package/src/history/index.ts +12 -0
  111. package/src/history/index.type.ts +50 -0
  112. package/src/history/index.vue +292 -0
  113. package/src/icon-button/index.ts +12 -0
  114. package/src/icon-button/index.type.ts +8 -0
  115. package/src/icon-button/index.vue +52 -0
  116. package/src/index.ts +33 -1
  117. package/src/prompts/prompt.vue +7 -21
  118. package/src/question/components/HotQuestions.vue +1 -1
  119. package/src/question/index.less +9 -10
  120. package/src/sender/components/TemplateEditor.vue +274 -0
  121. package/src/sender/index.less +17 -7
  122. package/src/sender/index.type.ts +51 -0
  123. package/src/sender/index.vue +56 -8
  124. package/src/sender/vars.less +3 -3
  125. package/src/suggestion/components/CategoryNav.vue +38 -0
  126. package/src/suggestion/components/SuggestionCapsule.vue +183 -0
  127. package/src/suggestion/components/SuggestionPanel.vue +147 -0
  128. package/src/suggestion/composables/useKeyboardNavigation.ts +101 -0
  129. package/src/suggestion/composables/useSuggestionFilter.ts +34 -0
  130. package/src/suggestion/composables/useTriggerDetection.ts +46 -0
  131. package/src/suggestion/index.less +497 -0
  132. package/src/suggestion/index.ts +12 -0
  133. package/src/suggestion/index.type.ts +101 -0
  134. package/src/suggestion/index.vue +338 -0
  135. package/src/suggestion/utils/dom.ts +66 -0
  136. package/src/suggestion/vars.less +141 -0
@@ -0,0 +1,338 @@
1
+ <script setup lang="ts">
2
+ import { ref, computed, watch, onMounted, onBeforeUnmount } from 'vue'
3
+ import SuggestionCapsule from './components/SuggestionCapsule.vue'
4
+ import SuggestionPanel from './components/SuggestionPanel.vue'
5
+ import { useTriggerDetection } from './composables/useTriggerDetection'
6
+ import type {
7
+ SuggestionItem,
8
+ SuggestionProps,
9
+ SuggestionEmits,
10
+ TriggerHandler,
11
+ TriggerInfo,
12
+ TriggerContext,
13
+ Category,
14
+ } from './index.type'
15
+ import { IconHotQuestion, IconArrowUp, IconArrowDown } from '@opentiny/tiny-robot-svgs'
16
+
17
+ import './index.less'
18
+
19
+ const props = withDefaults(defineProps<SuggestionProps>(), {
20
+ open: undefined,
21
+ theme: 'light',
22
+ loading: false,
23
+ title: '快捷指令',
24
+ items: () => [],
25
+ categories: () => [],
26
+ triggerKeys: () => ['/'],
27
+ maxVisibleItems: 5,
28
+ defaultExpanded: false,
29
+ closeOnOutsideClick: true,
30
+ })
31
+
32
+ const emit = defineEmits<SuggestionEmits>()
33
+
34
+ // 状态管理
35
+ const internalOpen = ref(false)
36
+ const currentItems = ref<SuggestionItem[]>([])
37
+ const triggerInfo = ref<TriggerContext>({
38
+ text: '',
39
+ position: 0,
40
+ })
41
+
42
+ // 是否展开完整指令列表
43
+ const isExpanded = ref(props.defaultExpanded)
44
+
45
+ // 是否显示展开按钮
46
+ const showExpandButton = ref(false)
47
+
48
+ // 切换指令列表的展开状态
49
+ const toggleExpand = () => {
50
+ isExpanded.value = !isExpanded.value
51
+ emit('update:expanded', isExpanded.value)
52
+ }
53
+
54
+ // 处理显示展开按钮
55
+ const handleShowExpandButton = (value: boolean) => {
56
+ showExpandButton.value = value
57
+ }
58
+
59
+ // 当前激活的分类
60
+ const activeCategory = ref<string>('')
61
+
62
+ // 当前选中的项目索引
63
+ const activeItemIndex = ref(-1)
64
+
65
+ // 元素引用
66
+ const rootRef = ref<HTMLElement | null>(null)
67
+ const panelRef = ref<InstanceType<typeof SuggestionPanel> | null>(null)
68
+
69
+ // 计算实际打开状态
70
+ const panelOpen = computed(() => (props.open !== undefined ? props.open : internalOpen.value))
71
+
72
+ // 计算当前激活分类的项目列表
73
+ const activeItems = computed(() => {
74
+ // 如果没有分类或没有选中分类,直接显示 items
75
+ if (props.categories.length === 0 || !activeCategory.value) {
76
+ return currentItems.value
77
+ }
78
+
79
+ // 查找当前激活的分类
80
+ const category = props.categories.find((cat) => cat.id === activeCategory.value)
81
+ return category ? category.items : []
82
+ })
83
+
84
+ // 监听打开状态变化,重置选中项
85
+ watch(panelOpen, (isOpen) => {
86
+ if (isOpen) {
87
+ // 初始化选中项
88
+ activeItemIndex.value = activeItems.value.length > 0 ? 0 : -1
89
+ } else {
90
+ // 重置选中项
91
+ activeItemIndex.value = -1
92
+ }
93
+ })
94
+
95
+ // 监听项目列表变化,更新选中项
96
+ watch(activeItems, (items) => {
97
+ if (items.length > 0 && activeItemIndex.value === -1) {
98
+ activeItemIndex.value = 0
99
+ } else if (items.length === 0) {
100
+ activeItemIndex.value = -1
101
+ } else if (activeItemIndex.value >= items.length) {
102
+ activeItemIndex.value = items.length - 1
103
+ }
104
+ })
105
+
106
+ // 初始化激活的分类
107
+ watch(
108
+ () => props.categories,
109
+ (categories) => {
110
+ if (categories.length > 0 && !activeCategory.value) {
111
+ activeCategory.value = categories[0].id
112
+ }
113
+ },
114
+ { immediate: true },
115
+ )
116
+
117
+ // 处理 items 数据
118
+ const processItems = () => {
119
+ currentItems.value = [...props.items]
120
+ }
121
+
122
+ // 初始化hooks
123
+ const { detectTrigger } = useTriggerDetection(props)
124
+
125
+ // 处理胶囊式指令点击
126
+ const handleSuggestionClick = (item: SuggestionItem) => {
127
+ // 发出事件,便于父组件处理回填
128
+ emit('suggestion-select', item)
129
+
130
+ // 如果存在触发信息,可以利用它进行回填
131
+ // 否则直接将值传递给父组件
132
+ emit('select', item.value, {
133
+ text: '',
134
+ position: 0,
135
+ })
136
+
137
+ // 如果指令包含模板,在选择后填充模板
138
+ if (item.template) {
139
+ emit('fill-template', item.template)
140
+ }
141
+ }
142
+
143
+ // 触发事件处理
144
+ const handleTrigger: TriggerHandler = (info: TriggerInfo) => {
145
+ if (info === false) {
146
+ closePanel()
147
+ } else {
148
+ // 保存触发信息,用于回填
149
+ if (typeof info === 'object' && info !== null) {
150
+ triggerInfo.value = {
151
+ text: info.text || '',
152
+ position: info.position || 0,
153
+ }
154
+ }
155
+ processItems()
156
+ internalOpen.value = true
157
+ emit('update:open', true)
158
+ }
159
+ }
160
+
161
+ // 核心功能:处理输入事件,用于检测触发字符
162
+ const handleInputEvent = (event: Event, text: string) => {
163
+ // 检测触发条件
164
+ const newTriggerInfo = detectTrigger(event, text)
165
+
166
+ if (newTriggerInfo) {
167
+ // 设置触发信息
168
+ triggerInfo.value = newTriggerInfo
169
+
170
+ // 触发指令面板
171
+ handleTrigger(newTriggerInfo)
172
+ return true
173
+ }
174
+
175
+ // 如果指令面板已打开,关闭面板
176
+ if (panelOpen.value && text === '') {
177
+ handleTrigger(false)
178
+ return true
179
+ }
180
+
181
+ return false
182
+ }
183
+
184
+ // 键盘事件处理,委托给面板组件
185
+ const handleKeyDown = (e: KeyboardEvent) => {
186
+ if (panelOpen.value && panelRef.value) {
187
+ panelRef.value.handleKeyDown(e)
188
+ return
189
+ }
190
+ }
191
+
192
+ // 关闭面板
193
+ const closePanel = () => {
194
+ if (props.open === undefined) {
195
+ internalOpen.value = false
196
+ }
197
+ emit('update:open', false)
198
+ emit('close')
199
+ }
200
+
201
+ // 处理分类选择
202
+ const handleCategorySelect = (category: Category) => {
203
+ activeCategory.value = category.id
204
+ // 重置选中项索引
205
+ activeItemIndex.value = 0
206
+
207
+ emit('category-select', category)
208
+ }
209
+
210
+ // 处理指令选择
211
+ const handleSelect = (value: SuggestionItem, context: TriggerContext) => {
212
+ emit('select', value.text, context)
213
+
214
+ // 如果指令包含模板,在选择后填充模板
215
+ if (value.template) {
216
+ emit('fill-template', value.template)
217
+ }
218
+
219
+ closePanel()
220
+ }
221
+
222
+ // 点击外部关闭
223
+ const handleClickOutside = (event: MouseEvent) => {
224
+ if (props.closeOnOutsideClick && panelOpen.value && rootRef.value && !rootRef.value.contains(event.target as Node)) {
225
+ closePanel()
226
+ }
227
+ }
228
+
229
+ // 按钮切换面板是否可见
230
+ const handleOpenPanel = () => {
231
+ if (panelOpen.value) {
232
+ closePanel()
233
+ } else {
234
+ processItems()
235
+ internalOpen.value = true
236
+ emit('update:open', true)
237
+ }
238
+ }
239
+
240
+ // 监听点击外部事件
241
+ onMounted(() => {
242
+ if (props.closeOnOutsideClick) {
243
+ document.addEventListener('click', handleClickOutside)
244
+ }
245
+ })
246
+
247
+ onBeforeUnmount(() => {
248
+ if (props.closeOnOutsideClick) {
249
+ document.removeEventListener('click', handleClickOutside)
250
+ }
251
+ })
252
+
253
+ // 暴露给父组件的方法
254
+ defineExpose({
255
+ trigger: handleTrigger,
256
+ keyDown: handleKeyDown,
257
+ input: handleInputEvent,
258
+ toggleExpand,
259
+ })
260
+ </script>
261
+
262
+ <template>
263
+ <div ref="rootRef" :class="['tr-suggestion', className, { 'tr-suggestion--dark': theme === 'dark' }]">
264
+ <div class="tr-suggestion__header">
265
+ <div class="tr-suggestion__trigger" @click="handleOpenPanel">
266
+ <IconHotQuestion />
267
+ </div>
268
+
269
+ <!-- 胶囊式指令 -->
270
+ <SuggestionCapsule
271
+ :suggestions="items"
272
+ :isExpanded="isExpanded"
273
+ @suggestion-click="handleSuggestionClick"
274
+ @show-expand-button="handleShowExpandButton"
275
+ >
276
+ <template #suggestion-icon="slotProps">
277
+ <slot name="capsule-icon" :suggestion="slotProps.suggestion">
278
+ <IconEdit />
279
+ </slot>
280
+ </template>
281
+ </SuggestionCapsule>
282
+
283
+ <!-- 常规指令完整内容触发按钮 -->
284
+ <div v-if="showExpandButton" class="tr-suggestion__expand-button" @click="toggleExpand">
285
+ <IconArrowUp v-if="!isExpanded" />
286
+ <IconArrowDown v-else />
287
+ </div>
288
+ </div>
289
+
290
+ <!-- 自定义输入区域 -->
291
+ <slot name="trigger" :onTrigger="handleTrigger" :onKeyDown="handleKeyDown" :onInput="handleInputEvent">
292
+ <!-- 默认输入框实现 -->
293
+ </slot>
294
+
295
+ <!-- 指令面板(弹窗显示在输入框上方) -->
296
+ <SuggestionPanel
297
+ v-if="panelOpen"
298
+ ref="panelRef"
299
+ class="tr-suggestion-panel placement-top"
300
+ :items="currentItems"
301
+ :categories="categories"
302
+ :loading="loading"
303
+ :title="title"
304
+ :maxVisibleItems="maxVisibleItems"
305
+ :triggerContext="triggerInfo"
306
+ @close="closePanel"
307
+ @select="handleSelect"
308
+ @category-select="handleCategorySelect"
309
+ >
310
+ <!-- 转发所有插槽到面板组件 -->
311
+ <template #title-icon>
312
+ <slot name="title-icon">
313
+ <IconHotQuestion style="font-size: 36px" />
314
+ </slot>
315
+ </template>
316
+
317
+ <template #category-label="slotProps">
318
+ <slot name="category-label" :category="slotProps.category"></slot>
319
+ </template>
320
+
321
+ <template #item="slotProps">
322
+ <slot name="item" :item="slotProps.item" :active="slotProps.active"></slot>
323
+ </template>
324
+
325
+ <template #loading-indicator>
326
+ <slot name="loading-indicator">
327
+ <div class="tr-suggestion__loading-spinner"></div>
328
+ </slot>
329
+ </template>
330
+
331
+ <template #empty>
332
+ <slot name="empty">
333
+ <p>无匹配结果</p>
334
+ </slot>
335
+ </template>
336
+ </SuggestionPanel>
337
+ </div>
338
+ </template>
@@ -0,0 +1,66 @@
1
+ /**
2
+ * 测量元素文本宽度
3
+ * @param text 要测量的文本
4
+ * @param className 应用的样式类名
5
+ * @returns 测量后的宽度
6
+ */
7
+ export function measureTextWidth(text: string, className: string = ''): number {
8
+ // 创建临时元素
9
+ const temp = document.createElement('div')
10
+ if (className) {
11
+ temp.className = className
12
+ }
13
+
14
+ // 设置样式确保准确测量
15
+ temp.style.visibility = 'hidden'
16
+ temp.style.position = 'absolute'
17
+ temp.style.whiteSpace = 'nowrap'
18
+ temp.textContent = text
19
+
20
+ // 添加到DOM并测量
21
+ document.body.appendChild(temp)
22
+ const width = temp.offsetWidth
23
+ document.body.removeChild(temp)
24
+
25
+ return width
26
+ }
27
+
28
+ /**
29
+ * 确保元素在容器中可见
30
+ * @param container 容器元素
31
+ * @param element 需要显示的元素
32
+ */
33
+ export function ensureElementVisible(container: HTMLElement, element: HTMLElement): void {
34
+ const containerRect = container.getBoundingClientRect()
35
+ const elementRect = element.getBoundingClientRect()
36
+
37
+ if (elementRect.bottom > containerRect.bottom) {
38
+ // 元素底部超出容器
39
+ container.scrollTop += elementRect.bottom - containerRect.bottom
40
+ } else if (elementRect.top < containerRect.top) {
41
+ // 元素顶部超出容器
42
+ container.scrollTop -= containerRect.top - elementRect.top
43
+ }
44
+ }
45
+
46
+ // 文本宽度缓存
47
+ const widthCache = new Map<string, number>()
48
+
49
+ /**
50
+ * 带缓存的文本宽度测量
51
+ * @param text 要测量的文本
52
+ * @param className 样式类名
53
+ * @returns 测量后的宽度
54
+ */
55
+ export function getCachedTextWidth(text: string, className: string = ''): number {
56
+ const key = `${text}::${className}`
57
+
58
+ if (widthCache.has(key)) {
59
+ return widthCache.get(key)!
60
+ }
61
+
62
+ const width = measureTextWidth(text, className)
63
+ widthCache.set(key, width)
64
+
65
+ return width
66
+ }
@@ -0,0 +1,141 @@
1
+ /* ----------------- 颜色变量 ----------------- */
2
+ :root {
3
+ /* 主题基础颜色 */
4
+ --tr-suggestion-primary-color: #1890ff;
5
+ --tr-suggestion-background-color: #ffffff;
6
+ --tr-suggestion-modal-background-color: #ffffff;
7
+ --tr-suggestion-text-color: #333333;
8
+ --tr-suggestion-text-color-secondary: #666666;
9
+ --tr-suggestion-border-color: #e8e8e8;
10
+ --tr-suggestion-hover-color: #f5f5f5;
11
+ --tr-suggestion-tab-hover-bg: #f0f0f0;
12
+ --tr-suggestion-active-tab-color: var(--tr-suggestion-primary-color);
13
+ --tr-suggestion-active-tab-bg: #e6f7ff;
14
+
15
+ /* 弹窗相关颜色 */
16
+ --tr-suggestion-header-bg: #f9f9f9;
17
+ --tr-suggestion-title-color: #1d2129;
18
+ --tr-suggestion-close-icon-color: #86909c;
19
+ --tr-suggestion-tab-active-bg: #e8f3ff;
20
+ --tr-suggestion-tab-active-text: #1890ff;
21
+ --tr-suggestion-tab-text: #4e5969;
22
+ --tr-suggestion-tab-border: #f0f0f0;
23
+ --tr-suggestion-list-divider-color: #f0f0f0;
24
+ --tr-suggestion-modal-backdrop-color: rgba(0, 0, 0, 0.5);
25
+
26
+ /* 常见内容颜色 */
27
+ --tr-suggestion-common-bg: #fff;
28
+ --tr-suggestion-common-text: #191919;
29
+ --tr-suggestion-common-hover-bg: #ebebeb;
30
+ --tr-suggestion-common-shadow: rgba(0, 0, 0, 0.04);
31
+
32
+ /* 背景颜色 */
33
+ --tr-suggestion-container-bg: #f8f8f8;
34
+ --tr-suggestion-list-item-bg: #fff;
35
+ --tr-suggestion-list-hover-shadow: rgba(0, 0, 0, 0.08);
36
+ --tr-suggestion-category-bg: rgba(0, 0, 0, 0.04);
37
+ --tr-suggestion-category-hover-bg: rgba(0, 0, 0, 0.08);
38
+ --tr-suggestion-category-active-border: #191919;
39
+ --tr-suggestion-item-border-color: rgba(0, 0, 0, 0.04);
40
+
41
+ /* 滚动条颜色 */
42
+ --tr-suggestion-scrollbar-track-bg: rgba(16, 31, 28, 0.1);
43
+ --tr-suggestion-scrollbar-thumb-bg: rgba(144, 147, 153, 0.5);
44
+ --tr-suggestion-scrollbar-thumb-hover-bg: rgba(144, 147, 153, 0.3);
45
+
46
+ /* ----------------- 尺寸变量 ----------------- */
47
+ /* 圆角 */
48
+ --tr-suggestion-border-radius: 24px;
49
+ --tr-suggestion-category-border-radius: 8px;
50
+ --tr-suggestion-list-border-radius: 12px;
51
+ --tr-suggestion-common-border-radius: 16px;
52
+ --tr-suggestion-scrollbar-border-radius: 2em;
53
+
54
+ /* 间距和尺寸 */
55
+ --tr-suggestion-spacing: 16px;
56
+ --tr-suggestion-icon-size: 16px;
57
+ --tr-suggestion-container-height: 46px;
58
+ --tr-suggestion-item-height: 85px;
59
+ --tr-suggestion-trigger-size: 32px;
60
+ --tr-suggestion-common-item-height: 32px;
61
+ --tr-suggestion-category-height: 38px;
62
+ --tr-suggestion-scrollbar-width: 4px;
63
+ --tr-suggestion-modal-padding: 20px;
64
+ --tr-suggestion-modal-max-height: 553px;
65
+ --tr-suggestion-modal-max-width: 640px;
66
+ --tr-suggestion-content-max-height: calc(553px - 120px);
67
+ --tr-suggestion-z-index: 1000;
68
+
69
+ /* ----------------- 文字变量 ----------------- */
70
+ /* 字体 */
71
+ --tr-suggestion-font-size: 14px;
72
+ --tr-suggestion-title-font-size: 18px;
73
+ --tr-suggestion-title-font-weight: 600;
74
+ --tr-suggestion-item-font-weight: 500;
75
+ --tr-suggestion-line-height: 1.5;
76
+ --tr-suggestion-item-line-height: 22px;
77
+ --tr-suggestion-item-extra-font-size: 14px;
78
+ --tr-suggestion-item-extra-color: #191919;
79
+
80
+ /* ----------------- 特效变量 ----------------- */
81
+ /* 阴影 */
82
+ --tr-suggestion-panel-shadow:
83
+ 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 9px 28px 8px rgba(0, 0, 0, 0.05);
84
+ --tr-suggestion-trigger-shadow: 0 4px 16px rgba(0, 0, 0, 0.04);
85
+ --tr-suggestion-common-item-shadow: 0 4px 16px rgba(0, 0, 0, 0.04);
86
+ --tr-suggestion-list-item-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
87
+ --tr-suggestion-wrap-trigger-shadow: 2px 0 9px rgba(0, 0, 0, 0.04);
88
+
89
+ /* 动画 */
90
+ --tr-suggestion-transition-duration: 0.3s;
91
+ --tr-suggestion-transition-timing: ease;
92
+ --tr-suggestion-hover-transition: all var(--tr-suggestion-transition-duration) var(--tr-suggestion-transition-timing);
93
+ }
94
+
95
+ /* ----------------- 暗色主题变量 ----------------- */
96
+ [data-theme='dark'],
97
+ .theme-dark {
98
+ /* 主题基础颜色 */
99
+ --tr-suggestion-primary-color: #177ddc;
100
+ --tr-suggestion-background-color: #1f1f1f;
101
+ --tr-suggestion-modal-background-color: #2a2a2a;
102
+ --tr-suggestion-text-color: #f0f0f0;
103
+ --tr-suggestion-text-color-secondary: #aaaaaa;
104
+ --tr-suggestion-border-color: #434343;
105
+ --tr-suggestion-hover-color: #303030;
106
+ --tr-suggestion-tab-hover-bg: #3a3a3a;
107
+ --tr-suggestion-active-tab-color: var(--tr-suggestion-primary-color);
108
+ --tr-suggestion-active-tab-bg: #113a5c;
109
+
110
+ /* 弹窗相关颜色 */
111
+ --tr-suggestion-header-bg: #2a2a2a;
112
+ --tr-suggestion-title-color: #c9d1d9;
113
+ --tr-suggestion-close-icon-color: #8b949e;
114
+ --tr-suggestion-tab-active-bg: #30363d;
115
+ --tr-suggestion-tab-active-text: #58a6ff;
116
+ --tr-suggestion-tab-text: #8b949e;
117
+ --tr-suggestion-tab-border: #30363d;
118
+ --tr-suggestion-list-divider-color: #30363d;
119
+ --tr-suggestion-modal-backdrop-color: rgba(0, 0, 0, 0.7);
120
+
121
+ /* 常见内容颜色 */
122
+ --tr-suggestion-common-bg: #2a2a2a;
123
+ --tr-suggestion-common-text: #e6e6e6;
124
+ --tr-suggestion-common-hover-bg: #3a3a3a;
125
+ --tr-suggestion-common-shadow: rgba(0, 0, 0, 0.2);
126
+
127
+ /* 背景颜色 */
128
+ --tr-suggestion-container-bg: #141414;
129
+ --tr-suggestion-list-item-bg: #2a2a2a;
130
+ --tr-suggestion-list-hover-shadow: rgba(0, 0, 0, 0.3);
131
+ --tr-suggestion-category-bg: rgba(255, 255, 255, 0.04);
132
+ --tr-suggestion-category-hover-bg: rgba(255, 255, 255, 0.08);
133
+ --tr-suggestion-category-active-border: #e6e6e6;
134
+ --tr-suggestion-item-border-color: rgba(255, 255, 255, 0.04);
135
+
136
+ /* 滚动条颜色 */
137
+ --tr-suggestion-scrollbar-track-bg: rgba(255, 255, 255, 0.05);
138
+ --tr-suggestion-scrollbar-thumb-bg: rgba(255, 255, 255, 0.2);
139
+ --tr-suggestion-scrollbar-thumb-hover-bg: rgba(255, 255, 255, 0.3);
140
+ --tr-suggestion-item-extra-color: #aaaaaa;
141
+ }