@firerian/fireui 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +74 -0
- package/dist/fireui.cjs +2 -0
- package/dist/fireui.cjs.map +1 -0
- package/dist/fireui.css +1 -0
- package/dist/fireui.es.mjs +3867 -0
- package/dist/fireui.es.mjs.map +1 -0
- package/dist/fireui.umd.js +2 -0
- package/dist/fireui.umd.js.map +1 -0
- package/dist/types/index.d.ts +1590 -0
- package/package.json +132 -0
- package/src/components/button/button.test.ts +357 -0
- package/src/components/button/button.vue +366 -0
- package/src/components/button/index.ts +17 -0
- package/src/components/button/types.ts +76 -0
- package/src/components/form/form-item.vue +136 -0
- package/src/components/form/form.vue +76 -0
- package/src/components/form/index.ts +16 -0
- package/src/components/grid/col.vue +99 -0
- package/src/components/grid/index.ts +16 -0
- package/src/components/grid/row.vue +85 -0
- package/src/components/grid/types.ts +66 -0
- package/src/components/index.ts +36 -0
- package/src/components/input/index.ts +8 -0
- package/src/components/input/input.test.ts +129 -0
- package/src/components/input/input.vue +256 -0
- package/src/components/input/types.ts +100 -0
- package/src/components/layout/aside.vue +89 -0
- package/src/components/layout/container.vue +53 -0
- package/src/components/layout/footer.vue +57 -0
- package/src/components/layout/header.vue +56 -0
- package/src/components/layout/index.ts +28 -0
- package/src/components/layout/main.vue +36 -0
- package/src/components/layout/types.ts +74 -0
- package/src/components/table/index.ts +16 -0
- package/src/components/table/table-column.vue +69 -0
- package/src/components/table/table.vue +354 -0
- package/src/components/tips/index.ts +12 -0
- package/src/components/tips/tips.test.ts +96 -0
- package/src/components/tips/tips.vue +206 -0
- package/src/components/tips/types.ts +56 -0
- package/src/components/tooltip/index.ts +8 -0
- package/src/components/tooltip/tooltip.test.ts +187 -0
- package/src/components/tooltip/tooltip.vue +261 -0
- package/src/components/tooltip/types.ts +60 -0
- package/src/hooks/useForm.ts +233 -0
- package/src/hooks/useTable.ts +153 -0
- package/src/index.ts +48 -0
- package/src/styles/main.scss +6 -0
- package/src/styles/mixins.scss +48 -0
- package/src/styles/reset.scss +49 -0
- package/src/styles/variables.scss +137 -0
- package/src/types/component.ts +9 -0
- package/src/types/form.ts +149 -0
- package/src/types/global.d.ts +49 -0
- package/src/types/grid.ts +76 -0
- package/src/types/index.ts +23 -0
- package/src/types/table.ts +181 -0
- package/src/types/tooltip.ts +44 -0
- package/src/utils/auto-import.ts +41 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/install.ts +20 -0
- package/src/utils/useNamespace.ts +29 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import Tooltip from './tooltip.vue'
|
|
2
|
+
import { withInstall } from '../../utils'
|
|
3
|
+
import type { App } from 'vue'
|
|
4
|
+
|
|
5
|
+
const FireTooltip = withInstall(Tooltip as any) as typeof Tooltip & { install: (app: App) => void }
|
|
6
|
+
|
|
7
|
+
export { FireTooltip }
|
|
8
|
+
export default FireTooltip
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
2
|
+
import { mount } from '@vue/test-utils'
|
|
3
|
+
import { FireTooltip } from './index'
|
|
4
|
+
|
|
5
|
+
describe('FireTooltip', () => {
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
// 清理 DOM
|
|
8
|
+
document.body.innerHTML = ''
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
it('should render correctly', () => {
|
|
12
|
+
const wrapper = mount(FireTooltip, {
|
|
13
|
+
props: {
|
|
14
|
+
content: 'Test tooltip'
|
|
15
|
+
},
|
|
16
|
+
slots: {
|
|
17
|
+
default: '<button>Hover me</button>'
|
|
18
|
+
}
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
expect(wrapper.exists()).toBe(true)
|
|
22
|
+
expect(wrapper.find('button').text()).toBe('Hover me')
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it('should show tooltip on hover', async () => {
|
|
26
|
+
const wrapper = mount(FireTooltip, {
|
|
27
|
+
props: {
|
|
28
|
+
content: 'Test tooltip',
|
|
29
|
+
trigger: 'hover'
|
|
30
|
+
},
|
|
31
|
+
slots: {
|
|
32
|
+
default: '<button>Hover me</button>'
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
// 初始状态应该隐藏
|
|
37
|
+
expect(document.querySelector('.fire-tooltip')).toBe(null)
|
|
38
|
+
|
|
39
|
+
// 模拟鼠标移入
|
|
40
|
+
await wrapper.find('button').trigger('mouseenter')
|
|
41
|
+
await wrapper.vm.$nextTick()
|
|
42
|
+
|
|
43
|
+
// 应该显示 tooltip
|
|
44
|
+
expect(document.querySelector('.fire-tooltip')).toBeTruthy()
|
|
45
|
+
|
|
46
|
+
// 模拟鼠标移出
|
|
47
|
+
await wrapper.find('button').trigger('mouseleave')
|
|
48
|
+
await wrapper.vm.$nextTick()
|
|
49
|
+
|
|
50
|
+
// 应该隐藏 tooltip
|
|
51
|
+
expect(document.querySelector('.fire-tooltip')).toBe(null)
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('should show tooltip on click', async () => {
|
|
55
|
+
const wrapper = mount(FireTooltip, {
|
|
56
|
+
props: {
|
|
57
|
+
content: 'Test tooltip',
|
|
58
|
+
trigger: 'click'
|
|
59
|
+
},
|
|
60
|
+
slots: {
|
|
61
|
+
default: '<button>Click me</button>'
|
|
62
|
+
}
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
// 初始状态应该隐藏
|
|
66
|
+
expect(document.querySelector('.fire-tooltip')).toBe(null)
|
|
67
|
+
|
|
68
|
+
// 模拟点击
|
|
69
|
+
await wrapper.find('button').trigger('click')
|
|
70
|
+
await wrapper.vm.$nextTick()
|
|
71
|
+
|
|
72
|
+
// 应该显示 tooltip
|
|
73
|
+
expect(document.querySelector('.fire-tooltip')).toBeTruthy()
|
|
74
|
+
|
|
75
|
+
// 再次点击
|
|
76
|
+
await wrapper.find('button').trigger('click')
|
|
77
|
+
await wrapper.vm.$nextTick()
|
|
78
|
+
|
|
79
|
+
// 应该隐藏 tooltip
|
|
80
|
+
expect(document.querySelector('.fire-tooltip')).toBe(null)
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
it('should show tooltip on focus', async () => {
|
|
84
|
+
const wrapper = mount(FireTooltip, {
|
|
85
|
+
props: {
|
|
86
|
+
content: 'Test tooltip',
|
|
87
|
+
trigger: 'focus'
|
|
88
|
+
},
|
|
89
|
+
slots: {
|
|
90
|
+
default: '<input type="text" placeholder="Focus me" />'
|
|
91
|
+
}
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
// 初始状态应该隐藏
|
|
95
|
+
expect(document.querySelector('.fire-tooltip')).toBe(null)
|
|
96
|
+
|
|
97
|
+
// 模拟聚焦
|
|
98
|
+
await wrapper.find('input').trigger('focus')
|
|
99
|
+
await wrapper.vm.$nextTick()
|
|
100
|
+
|
|
101
|
+
// 应该显示 tooltip
|
|
102
|
+
expect(document.querySelector('.fire-tooltip')).toBeTruthy()
|
|
103
|
+
|
|
104
|
+
// 模拟失焦
|
|
105
|
+
await wrapper.find('input').trigger('blur')
|
|
106
|
+
await wrapper.vm.$nextTick()
|
|
107
|
+
|
|
108
|
+
// 应该隐藏 tooltip
|
|
109
|
+
expect(document.querySelector('.fire-tooltip')).toBe(null)
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
it('should be disabled', async () => {
|
|
113
|
+
const wrapper = mount(FireTooltip, {
|
|
114
|
+
props: {
|
|
115
|
+
content: 'Test tooltip',
|
|
116
|
+
disabled: true,
|
|
117
|
+
trigger: 'hover'
|
|
118
|
+
},
|
|
119
|
+
slots: {
|
|
120
|
+
default: '<button>Hover me</button>'
|
|
121
|
+
}
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
// 模拟鼠标移入
|
|
125
|
+
await wrapper.find('button').trigger('mouseenter')
|
|
126
|
+
await wrapper.vm.$nextTick()
|
|
127
|
+
|
|
128
|
+
// 应该仍然隐藏
|
|
129
|
+
expect(document.querySelector('.fire-tooltip')).toBe(null)
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
it('should use slot content', async () => {
|
|
133
|
+
const wrapper = mount(FireTooltip, {
|
|
134
|
+
props: {
|
|
135
|
+
trigger: 'hover'
|
|
136
|
+
},
|
|
137
|
+
slots: {
|
|
138
|
+
default: '<button>Hover me</button>',
|
|
139
|
+
content: '<div>Custom tooltip content</div>'
|
|
140
|
+
}
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
// 模拟鼠标移入
|
|
144
|
+
await wrapper.find('button').trigger('mouseenter')
|
|
145
|
+
await wrapper.vm.$nextTick()
|
|
146
|
+
|
|
147
|
+
// 应该显示自定义内容
|
|
148
|
+
expect(document.querySelector('.fire-tooltip-content')?.textContent).toBe('Custom tooltip content')
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
it('should emit events', async () => {
|
|
152
|
+
const showSpy = vi.fn()
|
|
153
|
+
const hideSpy = vi.fn()
|
|
154
|
+
const updateVisibleSpy = vi.fn()
|
|
155
|
+
|
|
156
|
+
const wrapper = mount(FireTooltip, {
|
|
157
|
+
props: {
|
|
158
|
+
content: 'Test tooltip',
|
|
159
|
+
trigger: 'click'
|
|
160
|
+
},
|
|
161
|
+
slots: {
|
|
162
|
+
default: '<button>Click me</button>'
|
|
163
|
+
},
|
|
164
|
+
listeners: {
|
|
165
|
+
show: showSpy,
|
|
166
|
+
hide: hideSpy,
|
|
167
|
+
'update:visible': updateVisibleSpy
|
|
168
|
+
}
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
// 模拟点击
|
|
172
|
+
await wrapper.find('button').trigger('click')
|
|
173
|
+
await wrapper.vm.$nextTick()
|
|
174
|
+
|
|
175
|
+
// 应该触发 show 和 update:visible 事件
|
|
176
|
+
expect(showSpy).toHaveBeenCalled()
|
|
177
|
+
expect(updateVisibleSpy).toHaveBeenCalledWith(true)
|
|
178
|
+
|
|
179
|
+
// 再次点击
|
|
180
|
+
await wrapper.find('button').trigger('click')
|
|
181
|
+
await wrapper.vm.$nextTick()
|
|
182
|
+
|
|
183
|
+
// 应该触发 hide 和 update:visible 事件
|
|
184
|
+
expect(hideSpy).toHaveBeenCalled()
|
|
185
|
+
expect(updateVisibleSpy).toHaveBeenCalledWith(false)
|
|
186
|
+
})
|
|
187
|
+
})
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
ref="reference"
|
|
4
|
+
:class="ns.b"
|
|
5
|
+
@mouseenter="handleMouseEnter"
|
|
6
|
+
@mouseleave="handleMouseLeave"
|
|
7
|
+
@focus="handleFocus"
|
|
8
|
+
@blur="handleBlur"
|
|
9
|
+
>
|
|
10
|
+
<slot></slot>
|
|
11
|
+
<Teleport to="body">
|
|
12
|
+
<Transition name="fire-tooltip">
|
|
13
|
+
<div
|
|
14
|
+
v-if="isVisible"
|
|
15
|
+
ref="floating"
|
|
16
|
+
:class="[
|
|
17
|
+
ns.e('content'),
|
|
18
|
+
ns.m(position)
|
|
19
|
+
]"
|
|
20
|
+
:style="floatingStyles"
|
|
21
|
+
:id="tooltipId"
|
|
22
|
+
role="tooltip"
|
|
23
|
+
>
|
|
24
|
+
<div :class="ns.e('arrow')"></div>
|
|
25
|
+
<div :class="ns.e('inner')">
|
|
26
|
+
<slot name="content">{{ content }}</slot>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
</Transition>
|
|
30
|
+
</Teleport>
|
|
31
|
+
</div>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<script setup lang="ts">
|
|
35
|
+
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
|
|
36
|
+
import { useFloating, flip, offset, autoUpdate } from '@floating-ui/vue'
|
|
37
|
+
import { useNamespace } from '../../utils'
|
|
38
|
+
// 类型定义内联,避免模块解析问题
|
|
39
|
+
type TooltipPlacement = 'top' | 'bottom' | 'left' | 'right'
|
|
40
|
+
type TooltipTrigger = 'hover' | 'click' | 'focus'
|
|
41
|
+
|
|
42
|
+
const ns = useNamespace('tooltip')
|
|
43
|
+
|
|
44
|
+
// Props 定义 - 使用 export 导出
|
|
45
|
+
export interface TooltipProps {
|
|
46
|
+
content?: string
|
|
47
|
+
placement?: TooltipPlacement
|
|
48
|
+
trigger?: TooltipTrigger
|
|
49
|
+
disabled?: boolean
|
|
50
|
+
visible?: boolean
|
|
51
|
+
offset?: number
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const props = withDefaults(defineProps<TooltipProps>(), {
|
|
55
|
+
content: '',
|
|
56
|
+
placement: 'top',
|
|
57
|
+
trigger: 'hover',
|
|
58
|
+
disabled: false,
|
|
59
|
+
visible: false,
|
|
60
|
+
offset: 8
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
const emit = defineEmits<{
|
|
64
|
+
'update:visible': [value: boolean]
|
|
65
|
+
show: []
|
|
66
|
+
hide: []
|
|
67
|
+
}>()
|
|
68
|
+
|
|
69
|
+
const reference = ref<HTMLElement | null>(null)
|
|
70
|
+
const floating = ref<HTMLElement | null>(null)
|
|
71
|
+
const isVisible = ref(props.visible)
|
|
72
|
+
const tooltipId = `fire-tooltip-${Math.random().toString(36).substr(2, 9)}`
|
|
73
|
+
const position = ref(props.placement)
|
|
74
|
+
|
|
75
|
+
const { x, y, strategy } = useFloating(
|
|
76
|
+
reference,
|
|
77
|
+
floating,
|
|
78
|
+
{
|
|
79
|
+
placement: props.placement,
|
|
80
|
+
middleware: [
|
|
81
|
+
offset(props.offset),
|
|
82
|
+
flip()
|
|
83
|
+
],
|
|
84
|
+
whileElementsMounted: autoUpdate
|
|
85
|
+
}
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
const floatingStyles = computed(() => ({
|
|
89
|
+
position: strategy.value,
|
|
90
|
+
left: `${x.value ?? 0}px`,
|
|
91
|
+
top: `${y.value ?? 0}px`
|
|
92
|
+
}))
|
|
93
|
+
|
|
94
|
+
const show = () => {
|
|
95
|
+
if (props.disabled) return
|
|
96
|
+
isVisible.value = true
|
|
97
|
+
emit('update:visible', true)
|
|
98
|
+
emit('show')
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const hide = () => {
|
|
102
|
+
isVisible.value = false
|
|
103
|
+
emit('update:visible', false)
|
|
104
|
+
emit('hide')
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const handleMouseEnter = () => {
|
|
108
|
+
if (props.trigger === 'hover') {
|
|
109
|
+
show()
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const handleMouseLeave = () => {
|
|
114
|
+
if (props.trigger === 'hover') {
|
|
115
|
+
hide()
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const handleFocus = () => {
|
|
120
|
+
if (props.trigger === 'focus') {
|
|
121
|
+
show()
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const handleBlur = () => {
|
|
126
|
+
if (props.trigger === 'focus') {
|
|
127
|
+
hide()
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// 点击外部关闭
|
|
132
|
+
const handleClickOutside = (event: MouseEvent) => {
|
|
133
|
+
if (
|
|
134
|
+
reference.value &&
|
|
135
|
+
!reference.value.contains(event.target as Node) &&
|
|
136
|
+
floating.value &&
|
|
137
|
+
!floating.value.contains(event.target as Node)
|
|
138
|
+
) {
|
|
139
|
+
hide()
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
onMounted(() => {
|
|
144
|
+
if (props.trigger === 'click') {
|
|
145
|
+
document.addEventListener('click', handleClickOutside)
|
|
146
|
+
}
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
onUnmounted(() => {
|
|
150
|
+
if (props.trigger === 'click') {
|
|
151
|
+
document.removeEventListener('click', handleClickOutside)
|
|
152
|
+
}
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
// 监听 visible 变化
|
|
156
|
+
watch(() => props.visible, (val) => {
|
|
157
|
+
isVisible.value = val
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
// 清理
|
|
161
|
+
</script>
|
|
162
|
+
|
|
163
|
+
<style scoped lang="scss">
|
|
164
|
+
@import '../../styles/variables.scss';
|
|
165
|
+
|
|
166
|
+
.#{$namespace}-tooltip {
|
|
167
|
+
position: relative;
|
|
168
|
+
display: inline-block;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.#{$namespace}-tooltip__content {
|
|
172
|
+
position: absolute;
|
|
173
|
+
background-color: $tooltip-bg;
|
|
174
|
+
color: $tooltip-text;
|
|
175
|
+
padding: $tooltip-padding;
|
|
176
|
+
border-radius: $tooltip-border-radius;
|
|
177
|
+
font-size: $font-size-base;
|
|
178
|
+
line-height: 1.4;
|
|
179
|
+
max-width: 250px;
|
|
180
|
+
word-wrap: break-word;
|
|
181
|
+
pointer-events: auto;
|
|
182
|
+
box-shadow: $shadow-md;
|
|
183
|
+
z-index: 1000;
|
|
184
|
+
|
|
185
|
+
&--top {
|
|
186
|
+
bottom: 100%;
|
|
187
|
+
left: 50%;
|
|
188
|
+
transform: translateX(-50%);
|
|
189
|
+
margin-bottom: 8px;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
&--bottom {
|
|
193
|
+
top: 100%;
|
|
194
|
+
left: 50%;
|
|
195
|
+
transform: translateX(-50%);
|
|
196
|
+
margin-top: 8px;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
&--left {
|
|
200
|
+
right: 100%;
|
|
201
|
+
top: 50%;
|
|
202
|
+
transform: translateY(-50%);
|
|
203
|
+
margin-right: 8px;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
&--right {
|
|
207
|
+
left: 100%;
|
|
208
|
+
top: 50%;
|
|
209
|
+
transform: translateY(-50%);
|
|
210
|
+
margin-left: 8px;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.#{$namespace}-tooltip__arrow {
|
|
215
|
+
position: absolute;
|
|
216
|
+
width: 8px;
|
|
217
|
+
height: 8px;
|
|
218
|
+
background-color: $tooltip-bg;
|
|
219
|
+
transform: rotate(45deg);
|
|
220
|
+
|
|
221
|
+
.#{$namespace}-tooltip__content--top & {
|
|
222
|
+
bottom: -4px;
|
|
223
|
+
left: 50%;
|
|
224
|
+
transform: translateX(-50%) rotate(45deg);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.#{$namespace}-tooltip__content--bottom & {
|
|
228
|
+
top: -4px;
|
|
229
|
+
left: 50%;
|
|
230
|
+
transform: translateX(-50%) rotate(45deg);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.#{$namespace}-tooltip__content--left & {
|
|
234
|
+
right: -4px;
|
|
235
|
+
top: 50%;
|
|
236
|
+
transform: translateY(-50%) rotate(45deg);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.#{$namespace}-tooltip__content--right & {
|
|
240
|
+
left: -4px;
|
|
241
|
+
top: 50%;
|
|
242
|
+
transform: translateY(-50%) rotate(45deg);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// 动画效果
|
|
247
|
+
.fire-tooltip-enter-active,
|
|
248
|
+
.fire-tooltip-leave-active {
|
|
249
|
+
transition: opacity 0.2s ease, transform 0.2s ease;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.fire-tooltip-enter-from {
|
|
253
|
+
opacity: 0;
|
|
254
|
+
transform: scale(0.9);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
.fire-tooltip-leave-to {
|
|
258
|
+
opacity: 0;
|
|
259
|
+
transform: scale(0.9);
|
|
260
|
+
}
|
|
261
|
+
</style>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export interface TooltipProps {
|
|
2
|
+
/**
|
|
3
|
+
* 提示内容
|
|
4
|
+
*/
|
|
5
|
+
content?: string
|
|
6
|
+
/**
|
|
7
|
+
* 触发方式
|
|
8
|
+
*/
|
|
9
|
+
trigger?: 'hover' | 'click' | 'focus' | 'manual'
|
|
10
|
+
/**
|
|
11
|
+
* 禁用状态
|
|
12
|
+
*/
|
|
13
|
+
disabled?: boolean
|
|
14
|
+
/**
|
|
15
|
+
* 初始可见状态 (仅用于 manual 触发)
|
|
16
|
+
*/
|
|
17
|
+
visible?: boolean
|
|
18
|
+
/**
|
|
19
|
+
* 位置偏好
|
|
20
|
+
*/
|
|
21
|
+
placement?: 'top' | 'bottom' | 'left' | 'right'
|
|
22
|
+
/**
|
|
23
|
+
* 偏移量
|
|
24
|
+
*/
|
|
25
|
+
offset?: number
|
|
26
|
+
/**
|
|
27
|
+
* 自定义类名
|
|
28
|
+
*/
|
|
29
|
+
class?: string
|
|
30
|
+
/**
|
|
31
|
+
* 自定义样式
|
|
32
|
+
*/
|
|
33
|
+
style?: string | object
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface TooltipEmits {
|
|
37
|
+
/**
|
|
38
|
+
* 可见状态变化事件
|
|
39
|
+
*/
|
|
40
|
+
(e: 'update:visible', value: boolean): void
|
|
41
|
+
/**
|
|
42
|
+
* 显示事件
|
|
43
|
+
*/
|
|
44
|
+
(e: 'show'): void
|
|
45
|
+
/**
|
|
46
|
+
* 隐藏事件
|
|
47
|
+
*/
|
|
48
|
+
(e: 'hide'): void
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface TooltipSlots {
|
|
52
|
+
/**
|
|
53
|
+
* 触发元素
|
|
54
|
+
*/
|
|
55
|
+
default: () => any
|
|
56
|
+
/**
|
|
57
|
+
* 提示内容
|
|
58
|
+
*/
|
|
59
|
+
content?: () => any
|
|
60
|
+
}
|