@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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opentiny/tiny-robot",
3
- "version": "0.2.0-alpha.1",
3
+ "version": "0.2.0-alpha.2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -16,7 +16,7 @@
16
16
  "vue": "^3.3.11"
17
17
  },
18
18
  "dependencies": {
19
- "@opentiny/tiny-robot-svgs": "0.2.0-alpha.1",
19
+ "@opentiny/tiny-robot-svgs": "0.2.0-alpha.2",
20
20
  "@opentiny/vue": "^3.21.0",
21
21
  "@opentiny/vue-button": "^3.21.0",
22
22
  "@opentiny/vue-icon": "^3.22.0",
@@ -40,5 +40,5 @@
40
40
  "vue": "^3.3.11",
41
41
  "vue-tsc": "^2.2.8"
42
42
  },
43
- "gitHead": "3000951723ed8b1caa1361ebac131229bec9c237"
43
+ "gitHead": "f334d2ba1772fe0e2859d5f859980257e70f36e1"
44
44
  }
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import { IconMenu } from '@opentiny/tiny-robot-svgs'
3
+ import TinyTooltip from '@opentiny/vue-tooltip'
3
4
  import { onClickOutside, useWindowSize } from '@vueuse/core'
4
5
  import { computed, nextTick, ref, useTemplateRef, VNode, watch } from 'vue'
5
6
  import IconButton from '../icon-button'
@@ -108,32 +109,46 @@ watch(windowHeight, () => {
108
109
 
109
110
  <template>
110
111
  <div class="tr-action-group">
111
- <span
112
+ <tiny-tooltip
112
113
  v-for="(item, index) in list"
113
114
  :key="index"
114
- class="tr-action-group__btn-wrapper"
115
- @click="handleItemClick(item.props?.name)"
115
+ :content="item.props?.label"
116
+ effect="dark"
117
+ placement="top"
118
+ :open-delay="500"
119
+ :disabled="!props.showTooltip"
116
120
  >
117
- <component :is="item" />
118
- </span>
119
- <span v-if="showMore" ref="moreBtnRef" class="tr-action-group__btn-wrapper" @click="handleMoreClick">
120
- <slot name="moreBtn">
121
- <icon-button :icon="IconMenu" tooltip="更多" />
122
- </slot>
123
- <transition name="tr-action-group-dropdown">
124
- <ul v-show="showDropdown" ref="dropDownRef" :class="['tr-action-group__dropdown', dropDownPlacement]">
125
- <li
126
- class="tr-action-group__dropdown-item"
127
- v-for="(item, index) in moreList"
128
- :key="index"
129
- @click.stop="handleItemClick(item.props?.name)"
130
- >
131
- <component v-if="!props.dropDownShowLabelOnly" :is="item" />
132
- <span class="tr-action-group__dropdown-item-text">{{ item.props?.label }}</span>
133
- </li>
134
- </ul>
135
- </transition>
136
- </span>
121
+ <span class="tr-action-group__btn-wrapper" @click="handleItemClick(item.props?.name)">
122
+ <component :is="item" />
123
+ </span>
124
+ </tiny-tooltip>
125
+ <tiny-tooltip
126
+ v-if="showMore"
127
+ content="更多"
128
+ effect="dark"
129
+ placement="top"
130
+ :open-delay="500"
131
+ :disabled="!props.showTooltip"
132
+ >
133
+ <span ref="moreBtnRef" class="tr-action-group__btn-wrapper" @click="handleMoreClick">
134
+ <slot name="moreBtn">
135
+ <icon-button :icon="IconMenu" />
136
+ </slot>
137
+ <transition name="tr-action-group-dropdown">
138
+ <ul v-show="showDropdown" ref="dropDownRef" :class="['tr-action-group__dropdown', dropDownPlacement]">
139
+ <li
140
+ class="tr-action-group__dropdown-item"
141
+ v-for="(item, index) in moreList"
142
+ :key="index"
143
+ @click.stop="handleItemClick(item.props?.name)"
144
+ >
145
+ <component v-if="!props.dropDownShowLabelOnly" :is="item" />
146
+ <span class="tr-action-group__dropdown-item-text">{{ item.props?.label }}</span>
147
+ </li>
148
+ </ul>
149
+ </transition>
150
+ </span>
151
+ </tiny-tooltip>
137
152
  </div>
138
153
  </template>
139
154
 
@@ -2,6 +2,7 @@ import { VNode } from 'vue'
2
2
 
3
3
  export interface ActionGroupProps {
4
4
  maxNum?: number
5
+ showTooltip?: boolean
5
6
  dropDownShowLabelOnly?: boolean
6
7
  }
7
8
 
@@ -1,8 +1,7 @@
1
1
  <script setup lang="ts">
2
2
  import markdownit from 'markdown-it'
3
- import { computed, useSlots } from 'vue'
4
- import { CopyAction, RefreshAction } from './components/actions'
5
- import { BubbleActionOptions, BubbleEvents, BubbleProps, BubbleSlots } from './index.type'
3
+ import { computed } from 'vue'
4
+ import { BubbleProps, BubbleSlots } from './index.type'
6
5
 
7
6
  const props = withDefaults(defineProps<BubbleProps>(), {
8
7
  content: '',
@@ -11,72 +10,20 @@ const props = withDefaults(defineProps<BubbleProps>(), {
11
10
  maxWidth: '80%',
12
11
  })
13
12
 
14
- const emit = defineEmits<BubbleEvents>()
13
+ const slots = defineSlots<BubbleSlots>()
15
14
 
16
- defineSlots<BubbleSlots>()
17
-
18
- const slots = useSlots()
15
+ const markdownItInstance = computed(() => {
16
+ return markdownit(props.mdConfig || {})
17
+ })
19
18
 
20
19
  const bubbleContent = computed(() => {
21
20
  if (props.type === 'markdown') {
22
- return markdownit(props.mdConfig || {}).render(props.content)
21
+ return markdownItInstance.value.render(props.content)
23
22
  }
24
23
  return props.content
25
24
  })
26
25
 
27
26
  const placementStart = computed(() => props.placement === 'start')
28
-
29
- const defaultActionsMap = new Map<string, BubbleActionOptions>([
30
- [
31
- 'copy',
32
- {
33
- name: 'copy',
34
- vnode: CopyAction,
35
- show: true,
36
- },
37
- ],
38
- [
39
- 'refresh',
40
- {
41
- name: 'refresh',
42
- vnode: RefreshAction,
43
- show: true,
44
- },
45
- ],
46
- ])
47
-
48
- const computedActions = computed(() => {
49
- const actions = (props.actions || []).map((action) => {
50
- if (typeof action === 'string') {
51
- return defaultActionsMap.get(action)
52
- }
53
-
54
- if (defaultActionsMap.has(action.name)) {
55
- return {
56
- ...defaultActionsMap.get(action.name),
57
- ...action,
58
- }
59
- }
60
-
61
- return action
62
- })
63
-
64
- return actions.filter((action): action is BubbleActionOptions => Boolean(action))
65
- })
66
-
67
- const handleActionClick = (name: string, ...args: unknown[]) => {
68
- if (name === 'copy') {
69
- emit('copy', args[0] as boolean)
70
- return
71
- }
72
-
73
- if (name === 'refresh') {
74
- emit('refresh')
75
- return
76
- }
77
-
78
- emit('action', name, ...args)
79
- }
80
27
  </script>
81
28
 
82
29
  <template>
@@ -93,7 +40,7 @@ const handleActionClick = (name: string, ...args: unknown[]) => {
93
40
  <component :is="props.avatar"></component>
94
41
  </div>
95
42
  <div class="tr-bubble__content-wrapper">
96
- <slot v-if="props.loading" name="loading">
43
+ <slot v-if="props.loading" name="loading" :bubble-props="props">
97
44
  <div class="tr-bubble__loading">
98
45
  <span></span>
99
46
  <span></span>
@@ -102,26 +49,14 @@ const handleActionClick = (name: string, ...args: unknown[]) => {
102
49
  </slot>
103
50
  <div v-else :class="['tr-bubble__content']">
104
51
  <div class="tr-bubbule__body">
105
- <slot>
52
+ <slot :bubble-props="props">
106
53
  <span v-if="props.type === 'markdown'" v-html="bubbleContent"></span>
107
54
  <span v-else>{{ bubbleContent }}</span>
108
55
  <span v-if="props.aborted" class="tr-bubbule__aborted">(用户停止)</span>
109
56
  </slot>
110
57
  </div>
111
- <div v-if="slots.footer || computedActions.length > 0" class="tr-bubbule__footer">
112
- <div class="tr-bubbule__footer-left">
113
- <slot name="footer"></slot>
114
- </div>
115
- <div class="tr-bubbule__footer-actions">
116
- <template v-for="action in computedActions" :key="action?.name">
117
- <component
118
- :is="action.vnode"
119
- v-show="typeof action.show === 'function' ? action.show(props) : action.show"
120
- :bubbleItem="props"
121
- @click="handleActionClick(action.name, $event)"
122
- ></component>
123
- </template>
124
- </div>
58
+ <div v-if="slots.footer" class="tr-bubbule__footer">
59
+ <slot name="footer" :bubble-props="props"></slot>
125
60
  </div>
126
61
  </div>
127
62
  </div>
@@ -203,6 +138,7 @@ const handleActionClick = (name: string, ...args: unknown[]) => {
203
138
  color: rgb(25, 25, 25);
204
139
  font-size: 16px;
205
140
  line-height: 26px;
141
+ word-break: break-word;
206
142
  }
207
143
 
208
144
  .tr-bubbule__aborted {
@@ -211,27 +147,7 @@ const handleActionClick = (name: string, ...args: unknown[]) => {
211
147
  }
212
148
 
213
149
  .tr-bubbule__footer {
214
- display: flex;
215
- gap: 12px;
216
-
217
- .tr-bubbule__footer-left {
218
- flex: 1;
219
- }
220
-
221
- .tr-bubbule__footer-actions {
222
- display: flex;
223
- flex-shrink: 0;
224
- gap: 4px;
225
- margin-top: 12px;
226
-
227
- & > * {
228
- display: flex;
229
- align-items: center;
230
- justify-content: center;
231
- width: 24px;
232
- height: 24px;
233
- }
234
- }
150
+ margin-top: 12px;
235
151
  }
236
152
  }
237
153
  </style>
@@ -0,0 +1,55 @@
1
+ <script setup lang="ts">
2
+ import { useScroll } from '@vueuse/core'
3
+ import { computed, useTemplateRef, watch } from 'vue'
4
+ import Bubble from './Bubble.vue'
5
+ import { BubbleListProps, BubbleProps, BubbleSlots } from './index.type'
6
+
7
+ const props = withDefaults(defineProps<BubbleListProps>(), {})
8
+
9
+ const scrollContainerRef = useTemplateRef<HTMLDivElement>('scrollContainer')
10
+ const { y } = useScroll(scrollContainerRef, {
11
+ behavior: 'smooth',
12
+ throttle: 100,
13
+ })
14
+ const lastBubble = computed(() => props.items.at(-1))
15
+
16
+ watch([() => props.items.length, () => lastBubble.value?.content], () => {
17
+ if (!props.autoScroll || !scrollContainerRef.value) {
18
+ return
19
+ }
20
+
21
+ y.value = scrollContainerRef.value.scrollHeight
22
+ })
23
+
24
+ const getItemProps = (item: BubbleProps & { slots?: BubbleSlots }): BubbleProps => {
25
+ const defaultConfig = item.role ? props.roles?.[item.role] || {} : {}
26
+ const { slots: _roleSlots, ...rest } = defaultConfig
27
+ const { slots: _itemSlots, ...restItem } = item
28
+ return { ...rest, ...restItem }
29
+ }
30
+
31
+ const getItemSlots = (item: BubbleProps & { slots?: BubbleSlots }): BubbleSlots => {
32
+ const defaultConfig = item.role ? props.roles?.[item.role] || {} : {}
33
+ return { ...defaultConfig.slots, ...item.slots }
34
+ }
35
+ </script>
36
+
37
+ <template>
38
+ <div class="tr-bubble-list" ref="scrollContainer">
39
+ <Bubble v-for="(item, index) in props.items" :key="item.id || index" v-bind="getItemProps(item)">
40
+ <template v-for="(_, slotName) in getItemSlots(item)" #[slotName]="slotProps" :key="slotName">
41
+ <component :is="getItemSlots(item)[slotName]" v-bind="slotProps" />
42
+ </template>
43
+ </Bubble>
44
+ </div>
45
+ </template>
46
+
47
+ <style lang="less" scoped>
48
+ .tr-bubble-list {
49
+ display: flex;
50
+ flex-direction: column;
51
+ gap: 16px;
52
+ overflow-y: auto;
53
+ padding: 16px;
54
+ }
55
+ </style>
@@ -1,6 +1,6 @@
1
1
  import { App } from 'vue'
2
- import BubbleComp from './bubble.vue'
3
- import BubbleListComp from './bubble-list.vue'
2
+ import BubbleComp from './Bubble.vue'
3
+ import BubbleListComp from './BubbleList.vue'
4
4
 
5
5
  BubbleComp.name = 'TrBubble'
6
6
 
@@ -1,13 +1,5 @@
1
1
  import { Options as MarkdownItOptions } from 'markdown-it'
2
- import { Component, CSSProperties, VNode } from 'vue'
3
-
4
- export interface BubbleActionOptions {
5
- name: 'copy' | 'refresh' | string
6
- vnode?: VNode | Component
7
- show?: boolean | ((props: BubbleProps) => boolean)
8
- }
9
-
10
- export type BubbleAction = 'copy' | 'refresh' | BubbleActionOptions
2
+ import { CSSProperties, VNode } from 'vue'
11
3
 
12
4
  export type BubblePalcement = 'start' | 'end'
13
5
 
@@ -33,28 +25,22 @@ export interface BubbleProps {
33
25
  * type 为 'markdown' 时,markdown 的配置项
34
26
  */
35
27
  mdConfig?: MarkdownItOptions
36
-
37
- actions?: BubbleAction[]
38
28
  // 样式相关
39
29
  maxWidth?: CSSProperties['maxWidth']
40
30
  }
41
31
 
42
32
  export interface BubbleSlots {
43
- default: () => unknown
44
- footer: () => unknown
45
- loading: () => unknown
33
+ default?: (slotProps: { bubbleProps: BubbleProps }) => unknown
34
+ footer?: (slotProps: { bubbleProps: BubbleProps }) => unknown
35
+ loading?: (slotProps: { bubbleProps: BubbleProps }) => unknown
46
36
  }
47
37
 
48
- export interface BubbleEvents {
49
- (e: 'copy', result: boolean): void
50
- (e: 'refresh'): void
51
- (e: 'action', name: string, ...args: unknown[]): void
38
+ export type BubbleRoleConfig = Pick<BubbleProps, 'placement' | 'avatar' | 'type' | 'mdConfig' | 'maxWidth'> & {
39
+ slots?: BubbleSlots
52
40
  }
53
41
 
54
- export type BubbleRoleConfig = Pick<BubbleProps, 'placement' | 'avatar' | 'type' | 'mdConfig' | 'actions' | 'maxWidth'>
55
-
56
42
  export interface BubbleListProps {
57
- items: BubbleProps[]
43
+ items: (BubbleProps & { slots?: BubbleSlots })[]
58
44
  /**
59
45
  * 每个角色的默认配置项
60
46
  */
@@ -1,6 +1,7 @@
1
1
  <script setup lang="ts">
2
2
  import { IconCancelFullScreen, IconClose, IconFullScreen } from '@opentiny/tiny-robot-svgs'
3
3
  import { computed } from 'vue'
4
+ import IconButton from '../icon-button'
4
5
  import { ContainerProps, ContainerSlots } from './index.type'
5
6
 
6
7
  const show = defineModel<ContainerProps['show']>('show', { required: true })
@@ -22,17 +23,16 @@ const IconFullScreenSwitcher = computed(() => (fullscreen.value ? IconCancelFull
22
23
  </slot>
23
24
  <div class="tr-container__header-operations">
24
25
  <slot name="operations"></slot>
25
- <button class="icon-btn" @click="$emit('update:fullscreen', !fullscreen)">
26
- <IconFullScreenSwitcher />
27
- </button>
28
- <button class="icon-btn" @click="$emit('update:show', false)">
29
- <IconClose />
30
- </button>
26
+ <icon-button
27
+ size="28"
28
+ svg-size="20"
29
+ :icon="IconFullScreenSwitcher"
30
+ @click="$emit('update:fullscreen', !fullscreen)"
31
+ ></icon-button>
32
+ <icon-button size="28" svg-size="20" :icon="IconClose" @click="$emit('update:show', false)"></icon-button>
31
33
  </div>
32
34
  </div>
33
- <div class="tr-container__body">
34
- <slot></slot>
35
- </div>
35
+ <slot></slot>
36
36
  <div class="tr-container__footer">
37
37
  <slot name="footer"></slot>
38
38
  </div>
@@ -95,34 +95,9 @@ const IconFullScreenSwitcher = computed(() => (fullscreen.value ? IconCancelFull
95
95
  .tr-container__header-operations {
96
96
  display: flex;
97
97
  gap: 8px;
98
-
99
- button.icon-btn {
100
- width: 28px;
101
- height: 28px;
102
- display: inline-flex;
103
- align-items: center;
104
- justify-content: center;
105
- border: none;
106
- border-radius: 8px;
107
- cursor: pointer;
108
- padding: 0;
109
- transition: background-color 0.3s;
110
-
111
- &:hover {
112
- background-color: rgba(0, 0, 0, 0.04);
113
- }
114
-
115
- &:active {
116
- background-color: rgba(0, 0, 0, 0.15);
117
- }
118
-
119
- svg {
120
- font-size: 20px;
121
- }
122
- }
123
98
  }
124
99
 
125
- .tr-container__body {
100
+ .tr-container__header + :slotted(*) {
126
101
  flex: 1;
127
102
  overflow-y: auto;
128
103
  }
@@ -42,8 +42,9 @@ const handleSourceList = () => {
42
42
  <template>
43
43
  <div class="tr-feedback">
44
44
  <div class="tr-feedback__operations">
45
- <div v-if="props.operations?.length" class="tr-feedback__operations-left">
45
+ <div class="tr-feedback__operations-left">
46
46
  <action-group
47
+ v-if="props.operations?.length"
47
48
  :max-num="props.operationsLimit"
48
49
  :drop-down-show-label-only="true"
49
50
  @item-click="handleOperation"
@@ -66,32 +67,31 @@ const handleSourceList = () => {
66
67
  </tiny-button>
67
68
  </template>
68
69
  </action-group>
69
- </div>
70
- <div v-else-if="props.sources?.length">
71
- <span class="tr-feedback__source" @click="handleSourceList">
72
- <span>{{ props.sources?.length }}条来源</span>
73
- <component :is="showSourceList ? IconArrowUp : IconArrowDown" />
74
- </span>
70
+ <div v-else-if="props.sources?.length">
71
+ <span class="tr-feedback__source" @click="handleSourceList">
72
+ <span>{{ props.sources?.length }}条来源</span>
73
+ <component :is="showSourceList ? IconArrowUp : IconArrowDown" />
74
+ </span>
75
+ </div>
75
76
  </div>
76
77
  <div class="tr-feedback__operations-right">
77
- <action-group :max-num="props.actionsLimit" @item-click="handleAction">
78
+ <action-group :max-num="props.actionsLimit" :show-tooltip="true" @item-click="handleAction">
78
79
  <action-group-item
79
80
  v-for="action in props.actions"
80
81
  :key="action.name"
81
82
  :name="action.name"
82
83
  :label="action.label"
83
84
  >
84
- <icon-button
85
- v-if="typeof action.icon === 'string'"
86
- :icon="iconMap[action.icon]"
87
- :tooltip="action.label"
88
- ></icon-button>
85
+ <icon-button v-if="typeof action.icon === 'string'" :icon="iconMap[action.icon]"></icon-button>
89
86
  <component v-else :is="action.icon"></component>
90
87
  </action-group-item>
91
88
  </action-group>
92
89
  </div>
93
90
  </div>
94
- <div class="tr-feedback__footer">
91
+ <div
92
+ v-if="(props.operations?.length && props.sources?.length) || (showSourceList && props.sources)"
93
+ class="tr-feedback__footer"
94
+ >
95
95
  <div v-if="props.operations?.length && props.sources?.length">
96
96
  <span class="tr-feedback__source" @click="handleSourceList">
97
97
  <span>{{ props.sources?.length }}条来源</span>
@@ -2,7 +2,6 @@ import { Component, VNode } from 'vue'
2
2
 
3
3
  export interface IconButtonProps {
4
4
  icon: VNode | Component
5
- size?: string
6
- svgSize?: string
7
- tooltip?: string
5
+ size?: string | number
6
+ svgSize?: string | number
8
7
  }
@@ -1,20 +1,26 @@
1
1
  <script setup lang="ts">
2
- import TinyTooltip from '@opentiny/vue-tooltip'
3
2
  import { IconButtonProps } from './index.type'
3
+ import { computed } from 'vue'
4
4
 
5
5
  const props = withDefaults(defineProps<IconButtonProps>(), {
6
6
  size: '24px',
7
7
  svgSize: '16px',
8
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))
9
20
  </script>
10
21
 
11
22
  <template>
12
- <tiny-tooltip v-if="tooltip" :content="tooltip" effect="dark" placement="top" :open-delay="500">
13
- <button class="tr-icon-button">
14
- <component :is="props.icon" />
15
- </button>
16
- </tiny-tooltip>
17
- <button v-else class="tr-icon-button">
23
+ <button class="tr-icon-button">
18
24
  <component :is="props.icon" />
19
25
  </button>
20
26
  </template>
@@ -25,8 +31,8 @@ button.tr-icon-button {
25
31
  --tr-icon-button-active-bg: rgba(0, 0, 0, 0.15);
26
32
  --tr-icon-button-border-radius: 8px;
27
33
 
28
- width: v-bind('props.size');
29
- height: v-bind('props.size');
34
+ width: v-bind('size');
35
+ height: v-bind('size');
30
36
  display: inline-flex;
31
37
  align-items: center;
32
38
  justify-content: center;
@@ -46,7 +52,7 @@ button.tr-icon-button {
46
52
  }
47
53
 
48
54
  svg {
49
- font-size: v-bind('props.svgSize');
55
+ font-size: v-bind('svgSize');
50
56
  }
51
57
  }
52
58
  </style>