hy-app 0.2.5 → 0.2.7
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/common/index.ts +2 -1
- package/common/shakeService.ts +60 -0
- package/components/hy-action-sheet/hy-action-sheet.vue +184 -0
- package/components/hy-action-sheet/index.scss +123 -0
- package/components/hy-action-sheet/props.ts +18 -0
- package/components/hy-action-sheet/typing.d.ts +96 -0
- package/components/hy-address-picker/hy-address-picker.vue +75 -91
- package/components/hy-avatar/hy-avatar.vue +64 -73
- package/components/hy-button/hy-button.vue +3 -3
- package/components/hy-button/typing.d.ts +35 -31
- package/components/hy-cell/typing.d.ts +27 -24
- package/components/hy-empty/hy-empty.vue +30 -37
- package/components/hy-empty/icon.ts +78 -0
- package/components/hy-empty/index.scss +2 -1
- package/components/hy-empty/props.ts +10 -9
- package/components/hy-empty/typing.d.ts +39 -14
- package/components/hy-float-button/hy-float-button.vue +183 -17
- package/components/hy-float-button/props.ts +17 -15
- package/components/hy-float-button/typing.d.ts +51 -27
- package/components/hy-icon/hy-icon.vue +39 -41
- package/components/hy-icon/props.ts +17 -16
- package/components/hy-icon/typing.d.ts +24 -20
- package/components/hy-image/hy-image.vue +69 -104
- package/components/hy-image/index.scss +21 -5
- package/components/hy-image/props.ts +11 -10
- package/components/hy-image/typing.d.ts +23 -19
- package/components/hy-modal/hy-modal.vue +42 -54
- package/components/hy-modal/index.scss +56 -32
- package/components/hy-modal/props.ts +15 -14
- package/components/hy-modal/typing.d.ts +23 -17
- package/components/hy-popover/hy-popover.vue +200 -0
- package/components/hy-popover/index.scss +83 -0
- package/components/hy-popover/props.ts +13 -0
- package/components/hy-popover/typing.d.ts +56 -0
- package/components/hy-popup/index.scss +2 -2
- package/components/hy-popup/props.ts +7 -7
- package/components/hy-popup/typing.d.ts +17 -17
- package/components/hy-qrcode/hy-qrcode.vue +44 -45
- package/components/hy-rate/props.ts +6 -6
- package/components/hy-signature/props.ts +14 -14
- package/components/hy-tooltip/index.scss +2 -2
- package/components/hy-transition/hy-transition.vue +64 -72
- package/components/hy-transition/typing.d.ts +10 -6
- package/composables/index.ts +4 -2
- package/composables/usePopover.ts +221 -0
- package/composables/useQueue.ts +52 -0
- package/libs/css/_config.scss +5 -0
- package/libs/css/_function.scss +89 -0
- package/libs/css/mixin.scss +146 -21
- package/libs/css/vars.css +3 -1
- package/package.json +2 -2
- package/theme.scss +2 -1
- package/utils/inside.ts +96 -108
- package/utils/inspect.ts +48 -40
- package/utils/utils.ts +170 -187
|
@@ -10,6 +10,9 @@
|
|
|
10
10
|
},
|
|
11
11
|
`hy-float-button__${shape}`,
|
|
12
12
|
]"
|
|
13
|
+
@touchmove.stop.prevent="handleTouchMove"
|
|
14
|
+
@touchstart="handleTouchStart"
|
|
15
|
+
@touchend="handleTouchEnd"
|
|
13
16
|
>
|
|
14
17
|
<view
|
|
15
18
|
:class="['hy-float-button__container']"
|
|
@@ -72,7 +75,8 @@ import { computed, type CSSProperties, getCurrentInstance, onMounted, ref, toRef
|
|
|
72
75
|
import type IProps from './typing'
|
|
73
76
|
import type { MenusType } from './typing'
|
|
74
77
|
import defaultProps from './props'
|
|
75
|
-
import { addUnit, getPx, getRect,
|
|
78
|
+
import { addUnit, getPx, getRect, guid, isH5 } from '../../utils'
|
|
79
|
+
import { HyApp } from '../../typing/modules/common'
|
|
76
80
|
|
|
77
81
|
// 组件
|
|
78
82
|
import HyIcon from '../hy-icon/hy-icon.vue'
|
|
@@ -82,8 +86,7 @@ const props = withDefaults(defineProps<IProps>(), defaultProps)
|
|
|
82
86
|
const {
|
|
83
87
|
menus,
|
|
84
88
|
customStyle,
|
|
85
|
-
|
|
86
|
-
bottom,
|
|
89
|
+
gap,
|
|
87
90
|
zIndex,
|
|
88
91
|
bgColor,
|
|
89
92
|
text,
|
|
@@ -91,6 +94,9 @@ const {
|
|
|
91
94
|
size,
|
|
92
95
|
fixed,
|
|
93
96
|
direction,
|
|
97
|
+
draggable,
|
|
98
|
+
position,
|
|
99
|
+
expandable,
|
|
94
100
|
} = toRefs(props)
|
|
95
101
|
const emit = defineEmits(['click', 'clickItem'])
|
|
96
102
|
|
|
@@ -103,7 +109,94 @@ const btnSize: AnyObject = {
|
|
|
103
109
|
const open = ref(false)
|
|
104
110
|
const rotate = computed(() => (open.value && !text.value ? '45deg' : '0deg'))
|
|
105
111
|
const soleId = `hy-float-button__${guid()}`
|
|
106
|
-
const
|
|
112
|
+
const fabSize = reactive({ width: 0, height: 0 }) // 悬浮按钮大小
|
|
113
|
+
const screen = reactive({ width: 0, height: 0 })
|
|
114
|
+
const currentCoordinate = reactive({
|
|
115
|
+
top: 0,
|
|
116
|
+
left: 0,
|
|
117
|
+
})
|
|
118
|
+
// 按下时坐标相对于元素的偏移量
|
|
119
|
+
const touchOffset = reactive({ x: 0, y: 0 })
|
|
120
|
+
const attractTransition = ref<boolean>(false)
|
|
121
|
+
const fabDirection = ref<HyApp.LeftRightType>('left')
|
|
122
|
+
const fabDirection2 = ref<HyApp.TopBottomType>('top')
|
|
123
|
+
const bounding = reactive({
|
|
124
|
+
minLeft: 10,
|
|
125
|
+
minTop: 10,
|
|
126
|
+
maxLeft: 380,
|
|
127
|
+
maxTop: 680,
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
onMounted(async () => {
|
|
131
|
+
await getFatRect()
|
|
132
|
+
await getBounding()
|
|
133
|
+
initPosition()
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
watch(
|
|
137
|
+
() => position.value,
|
|
138
|
+
() => initPosition(),
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* @description 初始化距离
|
|
143
|
+
* */
|
|
144
|
+
const initPosition = () => {
|
|
145
|
+
const { minLeft, minTop, maxLeft, maxTop } = bounding
|
|
146
|
+
const centerY = (maxTop + minTop) / 2
|
|
147
|
+
const centerX = (maxLeft + minLeft) / 2
|
|
148
|
+
|
|
149
|
+
switch (position.value) {
|
|
150
|
+
case 'left-top':
|
|
151
|
+
currentCoordinate.top = minTop
|
|
152
|
+
currentCoordinate.left = minLeft
|
|
153
|
+
fabDirection.value = 'left'
|
|
154
|
+
fabDirection2.value = 'top'
|
|
155
|
+
break
|
|
156
|
+
case 'right-top':
|
|
157
|
+
currentCoordinate.top = minTop
|
|
158
|
+
currentCoordinate.left = maxLeft
|
|
159
|
+
fabDirection.value = 'right'
|
|
160
|
+
fabDirection2.value = 'top'
|
|
161
|
+
break
|
|
162
|
+
case 'left-bottom':
|
|
163
|
+
currentCoordinate.top = maxTop
|
|
164
|
+
currentCoordinate.left = minLeft
|
|
165
|
+
fabDirection.value = 'left'
|
|
166
|
+
fabDirection2.value = 'bottom'
|
|
167
|
+
break
|
|
168
|
+
case 'right-bottom':
|
|
169
|
+
currentCoordinate.top = maxTop
|
|
170
|
+
currentCoordinate.left = maxLeft
|
|
171
|
+
fabDirection.value = 'right'
|
|
172
|
+
fabDirection2.value = 'bottom'
|
|
173
|
+
break
|
|
174
|
+
case 'left-center':
|
|
175
|
+
currentCoordinate.top = centerY
|
|
176
|
+
currentCoordinate.left = minLeft
|
|
177
|
+
fabDirection.value = 'left'
|
|
178
|
+
fabDirection2.value = 'bottom'
|
|
179
|
+
break
|
|
180
|
+
case 'right-center':
|
|
181
|
+
currentCoordinate.top = centerY
|
|
182
|
+
currentCoordinate.left = maxLeft
|
|
183
|
+
fabDirection.value = 'right'
|
|
184
|
+
fabDirection2.value = 'bottom'
|
|
185
|
+
break
|
|
186
|
+
case 'top-center':
|
|
187
|
+
currentCoordinate.top = minTop
|
|
188
|
+
currentCoordinate.left = centerX
|
|
189
|
+
fabDirection.value = 'left'
|
|
190
|
+
fabDirection2.value = 'top'
|
|
191
|
+
break
|
|
192
|
+
case 'bottom-center':
|
|
193
|
+
currentCoordinate.top = maxTop
|
|
194
|
+
currentCoordinate.left = centerX
|
|
195
|
+
fabDirection.value = 'left'
|
|
196
|
+
fabDirection2.value = 'bottom'
|
|
197
|
+
break
|
|
198
|
+
}
|
|
199
|
+
}
|
|
107
200
|
|
|
108
201
|
/**
|
|
109
202
|
* @description 获取组件大小
|
|
@@ -121,11 +214,12 @@ const getFloatBtnSize = computed(() => {
|
|
|
121
214
|
* */
|
|
122
215
|
const FloatButtonStyle = computed(() => {
|
|
123
216
|
const style: CSSProperties = {
|
|
124
|
-
|
|
125
|
-
left:
|
|
217
|
+
top: currentCoordinate.top + 'px',
|
|
218
|
+
left: currentCoordinate.left + 'px',
|
|
126
219
|
backgroundColor: bgColor.value,
|
|
127
220
|
zIndex: zIndex.value,
|
|
128
221
|
color: textColor.value,
|
|
222
|
+
transition: 'all ease 0.3s',
|
|
129
223
|
}
|
|
130
224
|
if (fixed.value) style.position = 'fixed'
|
|
131
225
|
|
|
@@ -140,7 +234,7 @@ const menusStyle = computed(() => {
|
|
|
140
234
|
|
|
141
235
|
// 判断横向展示还是纵向展示
|
|
142
236
|
if (direction.value === 'row') {
|
|
143
|
-
if (
|
|
237
|
+
if (fabDirection.value === 'right') {
|
|
144
238
|
style.transform = 'translateX(-100%)'
|
|
145
239
|
style.left = '100%'
|
|
146
240
|
style.paddingRight = getFloatBtnSize.value
|
|
@@ -155,32 +249,47 @@ const menusStyle = computed(() => {
|
|
|
155
249
|
? addUnit(getPx(getFloatBtnSize.value) * menus.value.length + getPx(getFloatBtnSize.value))
|
|
156
250
|
: 0
|
|
157
251
|
} else {
|
|
158
|
-
|
|
159
|
-
|
|
252
|
+
if (fabDirection2.value === 'top') {
|
|
253
|
+
style.transform = 'translateX(-100%)'
|
|
254
|
+
style.height = '100%'
|
|
255
|
+
style.left = getFloatBtnSize.value
|
|
256
|
+
style.top = '0px'
|
|
257
|
+
style.paddingTop = getFloatBtnSize.value
|
|
258
|
+
} else {
|
|
259
|
+
style.paddingBottom = getFloatBtnSize.value
|
|
260
|
+
style.bottom = 0
|
|
261
|
+
}
|
|
160
262
|
style.transition = 'height 0.5s ease'
|
|
161
263
|
style.width = getFloatBtnSize.value
|
|
162
264
|
style.height = open.value
|
|
163
265
|
? addUnit(getPx(getFloatBtnSize.value) * menus.value.length + getPx(getFloatBtnSize.value))
|
|
164
266
|
: 0
|
|
165
|
-
style.paddingBottom = getFloatBtnSize.value
|
|
166
267
|
}
|
|
167
268
|
return style
|
|
168
269
|
})
|
|
169
270
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
271
|
+
/**
|
|
272
|
+
* @description 获取悬浮按钮大小
|
|
273
|
+
* */
|
|
274
|
+
const getFatRect = () => {
|
|
275
|
+
return new Promise((resolve, reject) => {
|
|
276
|
+
getRect(`#${soleId}`, false, instance).then((rect) => {
|
|
277
|
+
const { width, height } = rect as UniApp.NodeInfo
|
|
278
|
+
fabSize.width = width
|
|
279
|
+
fabSize.height = height
|
|
280
|
+
resolve(rect)
|
|
281
|
+
})
|
|
175
282
|
})
|
|
176
|
-
}
|
|
283
|
+
}
|
|
177
284
|
|
|
178
285
|
/**
|
|
179
286
|
* @description 点击悬浮按钮
|
|
180
287
|
* */
|
|
181
288
|
const handleClick = () => {
|
|
182
289
|
emit('click')
|
|
183
|
-
|
|
290
|
+
if (expandable.value) {
|
|
291
|
+
open.value = !open.value
|
|
292
|
+
}
|
|
184
293
|
}
|
|
185
294
|
|
|
186
295
|
/**
|
|
@@ -195,6 +304,63 @@ const handleMenuItemClick = (temp: MenusType, index: number) => {
|
|
|
195
304
|
})
|
|
196
305
|
}
|
|
197
306
|
}
|
|
307
|
+
|
|
308
|
+
const getBounding = () => {
|
|
309
|
+
return new Promise((resolve) => {
|
|
310
|
+
const sysInfo = uni.getSystemInfoSync()
|
|
311
|
+
|
|
312
|
+
const { top = 16, left = 16, right = 16, bottom = 16 } = gap.value
|
|
313
|
+
screen.width = sysInfo.windowWidth
|
|
314
|
+
screen.height = isH5 ? sysInfo.windowTop + sysInfo.windowHeight : sysInfo.windowHeight
|
|
315
|
+
bounding.minTop = isH5 ? sysInfo.windowTop + top : top
|
|
316
|
+
bounding.minLeft = left
|
|
317
|
+
bounding.maxLeft = screen.width - fabSize.width - right
|
|
318
|
+
bounding.maxTop = screen.height - fabSize.height - bottom
|
|
319
|
+
resolve(bounding)
|
|
320
|
+
})
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const handleTouchStart = (e: TouchEvent) => {
|
|
324
|
+
if (!draggable.value) return
|
|
325
|
+
|
|
326
|
+
const touch = e.touches[0]
|
|
327
|
+
touchOffset.x = touch.clientX - getPx(currentCoordinate.left)
|
|
328
|
+
touchOffset.y = touch.clientY - getPx(currentCoordinate.top)
|
|
329
|
+
attractTransition.value = false
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
function handleTouchMove(e: TouchEvent) {
|
|
333
|
+
if (!draggable.value) return
|
|
334
|
+
|
|
335
|
+
const touch = e.touches[0]
|
|
336
|
+
const { minLeft, minTop, maxLeft, maxTop } = bounding
|
|
337
|
+
let x = touch.clientX - touchOffset.x
|
|
338
|
+
let y = touch.clientY - touchOffset.y
|
|
339
|
+
|
|
340
|
+
if (x < minLeft) x = minLeft
|
|
341
|
+
else if (x > maxLeft) x = maxLeft
|
|
342
|
+
|
|
343
|
+
if (y < minTop) y = minTop
|
|
344
|
+
else if (y > maxTop) y = maxTop
|
|
345
|
+
|
|
346
|
+
currentCoordinate.top = y
|
|
347
|
+
currentCoordinate.left = x
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
function handleTouchEnd() {
|
|
351
|
+
if (props.draggable === false) return
|
|
352
|
+
|
|
353
|
+
const screenCenterX = screen.width / 2
|
|
354
|
+
const fabCenterX = currentCoordinate.left + fabSize.width / 2
|
|
355
|
+
attractTransition.value = true
|
|
356
|
+
if (fabCenterX < screenCenterX) {
|
|
357
|
+
currentCoordinate.left = bounding.minLeft
|
|
358
|
+
fabDirection.value = 'left'
|
|
359
|
+
} else {
|
|
360
|
+
currentCoordinate.left = bounding.maxLeft
|
|
361
|
+
fabDirection.value = 'right'
|
|
362
|
+
}
|
|
363
|
+
}
|
|
198
364
|
</script>
|
|
199
365
|
|
|
200
366
|
<style scoped lang="scss">
|
|
@@ -1,25 +1,27 @@
|
|
|
1
|
-
import type IProps from
|
|
2
|
-
import { IconConfig } from
|
|
1
|
+
import type IProps from './typing'
|
|
2
|
+
import { IconConfig } from '../../config'
|
|
3
3
|
|
|
4
4
|
const defaultProps: IProps = {
|
|
5
5
|
menus: [],
|
|
6
|
-
direction:
|
|
6
|
+
direction: 'column',
|
|
7
7
|
icon: IconConfig.PLUS,
|
|
8
|
-
iconSize:
|
|
9
|
-
iconColor:
|
|
10
|
-
bottom:
|
|
11
|
-
left: 20,
|
|
8
|
+
iconSize: '',
|
|
9
|
+
iconColor: '',
|
|
10
|
+
gap: { left: 16, right: 16, top: 16, bottom: 40 },
|
|
12
11
|
zIndex: 10086,
|
|
13
|
-
bgColor:
|
|
14
|
-
text:
|
|
15
|
-
fontSize:
|
|
16
|
-
textColor:
|
|
17
|
-
size:
|
|
18
|
-
shape:
|
|
12
|
+
bgColor: '',
|
|
13
|
+
text: '',
|
|
14
|
+
fontSize: '12px',
|
|
15
|
+
textColor: '',
|
|
16
|
+
size: 'medium',
|
|
17
|
+
shape: 'circle',
|
|
19
18
|
opacity: 1,
|
|
20
19
|
shadow: true,
|
|
21
20
|
float: true,
|
|
22
21
|
fixed: true,
|
|
23
|
-
|
|
22
|
+
draggable: true,
|
|
23
|
+
position: 'right-bottom',
|
|
24
|
+
expandable: true,
|
|
25
|
+
}
|
|
24
26
|
|
|
25
|
-
export default defaultProps
|
|
27
|
+
export default defaultProps
|
|
@@ -1,93 +1,117 @@
|
|
|
1
|
-
import type { CSSProperties } from
|
|
1
|
+
import type { CSSProperties } from 'vue'
|
|
2
2
|
|
|
3
3
|
interface MenusVo {
|
|
4
4
|
/**
|
|
5
5
|
* @description 显示菜单文本
|
|
6
6
|
* */
|
|
7
|
-
label?: string
|
|
7
|
+
label?: string
|
|
8
8
|
/**
|
|
9
9
|
* @description 跳转路径
|
|
10
10
|
* */
|
|
11
|
-
url?: string
|
|
11
|
+
url?: string
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
export type MenusType = MenusVo | string
|
|
14
|
+
export type MenusType = MenusVo | string
|
|
15
|
+
export type IGap = {
|
|
16
|
+
left?: number
|
|
17
|
+
right?: number
|
|
18
|
+
top?: number
|
|
19
|
+
bottom?: number
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type FloatPositionVo =
|
|
23
|
+
| 'left-top'
|
|
24
|
+
| 'left-bottom'
|
|
25
|
+
| 'right-top'
|
|
26
|
+
| 'right-bottom'
|
|
27
|
+
| 'left-center'
|
|
28
|
+
| 'right-center'
|
|
29
|
+
| 'top-center'
|
|
30
|
+
| 'bottom-center'
|
|
15
31
|
|
|
16
32
|
export default interface HyFloatButtonProps {
|
|
17
33
|
/**
|
|
18
34
|
* @description 菜单栏集合
|
|
19
35
|
* */
|
|
20
|
-
menus?: MenusType[]
|
|
36
|
+
menus?: MenusType[]
|
|
21
37
|
/**
|
|
22
38
|
* @description 打开方向,row-横向;column-纵向
|
|
23
39
|
* */
|
|
24
|
-
direction?: HyApp.DirectionType
|
|
40
|
+
direction?: HyApp.DirectionType
|
|
25
41
|
/**
|
|
26
42
|
* @description 按钮显示的图标
|
|
27
43
|
* */
|
|
28
|
-
icon?: string
|
|
44
|
+
icon?: string
|
|
29
45
|
/**
|
|
30
46
|
* @description 按钮图标大小
|
|
31
47
|
* */
|
|
32
|
-
iconSize?: string | number
|
|
48
|
+
iconSize?: string | number
|
|
33
49
|
/**
|
|
34
50
|
* @description 按钮图标颜色
|
|
35
51
|
* */
|
|
36
|
-
iconColor?: string
|
|
52
|
+
iconColor?: string
|
|
37
53
|
/**
|
|
38
|
-
* @description
|
|
54
|
+
* @description 到边框最小距离
|
|
39
55
|
* */
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* @description 按钮距离左边的距离,默认单位为px
|
|
43
|
-
* */
|
|
44
|
-
left?: number | string;
|
|
56
|
+
gap?: IGap
|
|
45
57
|
/**
|
|
46
58
|
* @description 层级(默认:10086)
|
|
47
59
|
* */
|
|
48
|
-
zIndex?: number
|
|
60
|
+
zIndex?: number
|
|
49
61
|
/**
|
|
50
62
|
* @description 按钮背景颜色
|
|
51
63
|
* */
|
|
52
|
-
bgColor?: string
|
|
64
|
+
bgColor?: string
|
|
53
65
|
/**
|
|
54
66
|
* @description 按钮文字
|
|
55
67
|
* */
|
|
56
|
-
text?: string
|
|
68
|
+
text?: string
|
|
57
69
|
/**
|
|
58
70
|
* @description 按钮文字大小
|
|
59
71
|
* */
|
|
60
|
-
fontSize?: string | number
|
|
72
|
+
fontSize?: string | number
|
|
61
73
|
/**
|
|
62
74
|
* @description 按钮文字的颜色
|
|
63
75
|
* */
|
|
64
|
-
textColor?: string
|
|
76
|
+
textColor?: string
|
|
65
77
|
/**
|
|
66
78
|
* @description 按钮的尺寸
|
|
67
79
|
* */
|
|
68
|
-
size?: HyApp.SizeType | string | number
|
|
80
|
+
size?: HyApp.SizeType | string | number
|
|
69
81
|
/**
|
|
70
82
|
* @description 按钮的形状
|
|
71
83
|
* */
|
|
72
|
-
shape?: HyApp.ShapeType
|
|
84
|
+
shape?: HyApp.ShapeType
|
|
73
85
|
/**
|
|
74
86
|
* @description 按钮的透明度
|
|
75
87
|
* */
|
|
76
|
-
opacity?: number
|
|
88
|
+
opacity?: number
|
|
77
89
|
/**
|
|
78
90
|
* @description 是否显示阴影(默认:true)
|
|
79
91
|
* */
|
|
80
|
-
shadow?: boolean
|
|
92
|
+
shadow?: boolean
|
|
81
93
|
/**
|
|
82
94
|
* @description 是否显示漂浮的动画(默认:true)
|
|
83
95
|
* */
|
|
84
|
-
float?: boolean
|
|
96
|
+
float?: boolean
|
|
85
97
|
/**
|
|
86
98
|
* @description 是否固定位置(默认:true)
|
|
87
99
|
* */
|
|
88
|
-
fixed?: boolean
|
|
100
|
+
fixed?: boolean
|
|
101
|
+
/**
|
|
102
|
+
* @description 是否能拖动(默认:true)
|
|
103
|
+
* */
|
|
104
|
+
draggable?: boolean
|
|
105
|
+
/**
|
|
106
|
+
* @description 悬浮按钮位置 (默认:right-bottom)
|
|
107
|
+
* */
|
|
108
|
+
position?: FloatPositionVo
|
|
109
|
+
/**
|
|
110
|
+
* @description 禁用点击打开菜单栏
|
|
111
|
+
* */
|
|
112
|
+
expandable?: boolean
|
|
89
113
|
/**
|
|
90
114
|
* @description 定义需要用到的外部样式
|
|
91
115
|
* */
|
|
92
|
-
customStyle?: CSSProperties
|
|
116
|
+
customStyle?: CSSProperties
|
|
93
117
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<view class="hy-icon
|
|
2
|
+
<view :class="`hy-icon ${customClass} hy-icon--${labelPos}`" @tap="clickHandler">
|
|
3
3
|
<image
|
|
4
4
|
class="hy-icon__img"
|
|
5
5
|
v-if="isImg"
|
|
@@ -7,12 +7,7 @@
|
|
|
7
7
|
:mode="imgMode"
|
|
8
8
|
:style="[imgStyle, customStyle]"
|
|
9
9
|
></image>
|
|
10
|
-
<text
|
|
11
|
-
v-else
|
|
12
|
-
class="hy-icon__icon"
|
|
13
|
-
:class="uClasses"
|
|
14
|
-
:style="[iconStyle, customStyle]"
|
|
15
|
-
></text>
|
|
10
|
+
<text v-else class="hy-icon__icon" :class="uClasses" :style="[iconStyle, customStyle]"></text>
|
|
16
11
|
<!-- 这里进行空字符串判断,如果仅仅是v-if="label",可能会出现传递0的时候,结果也无法显示 -->
|
|
17
12
|
<text
|
|
18
13
|
v-if="label !== ''"
|
|
@@ -23,8 +18,9 @@
|
|
|
23
18
|
marginLeft: labelPos == 'right' ? addUnit(space) : 0,
|
|
24
19
|
marginTop: labelPos == 'bottom' ? addUnit(space) : 0,
|
|
25
20
|
}"
|
|
26
|
-
>{{ label }}</text
|
|
27
21
|
>
|
|
22
|
+
{{ label }}
|
|
23
|
+
</text>
|
|
28
24
|
</view>
|
|
29
25
|
</template>
|
|
30
26
|
|
|
@@ -34,18 +30,18 @@ export default {
|
|
|
34
30
|
options: {
|
|
35
31
|
addGlobalClass: true,
|
|
36
32
|
virtualHost: true,
|
|
37
|
-
styleIsolation: 'shared'
|
|
38
|
-
}
|
|
33
|
+
styleIsolation: 'shared',
|
|
34
|
+
},
|
|
39
35
|
}
|
|
40
36
|
</script>
|
|
41
37
|
|
|
42
38
|
<script setup lang="ts">
|
|
43
|
-
import { computed, type CSSProperties, toRefs } from
|
|
44
|
-
import { addUnit } from
|
|
45
|
-
import defaultProps from
|
|
46
|
-
import type IProps from
|
|
39
|
+
import { computed, type CSSProperties, toRefs } from 'vue'
|
|
40
|
+
import { addUnit } from '../../utils'
|
|
41
|
+
import defaultProps from './props'
|
|
42
|
+
import type IProps from './typing'
|
|
47
43
|
|
|
48
|
-
const props = withDefaults(defineProps<IProps>(), defaultProps)
|
|
44
|
+
const props = withDefaults(defineProps<IProps>(), defaultProps)
|
|
49
45
|
const {
|
|
50
46
|
customPrefix,
|
|
51
47
|
name,
|
|
@@ -59,66 +55,68 @@ const {
|
|
|
59
55
|
index,
|
|
60
56
|
isRotate,
|
|
61
57
|
round,
|
|
62
|
-
|
|
63
|
-
|
|
58
|
+
customClass,
|
|
59
|
+
customStyle,
|
|
60
|
+
} = toRefs(props)
|
|
61
|
+
const emit = defineEmits(['click'])
|
|
64
62
|
|
|
65
63
|
const uClasses = computed(() => {
|
|
66
64
|
let classes: string | string[] = [
|
|
67
|
-
|
|
65
|
+
'iconfont',
|
|
68
66
|
`${customPrefix.value}-${name.value}`,
|
|
69
67
|
customPrefix.value,
|
|
70
|
-
]
|
|
71
|
-
if (isRotate.value) classes.push(
|
|
68
|
+
]
|
|
69
|
+
if (isRotate.value) classes.push('hy-rotate')
|
|
72
70
|
if (color.value)
|
|
73
71
|
// 主题色,通过类配置
|
|
74
|
-
classes.push(
|
|
72
|
+
classes.push('hy-icon__icon--' + color.value)
|
|
75
73
|
// 阿里,头条,百度小程序通过数组绑定类名时,无法直接使用[a, b, c]的形式,否则无法识别
|
|
76
74
|
// 故需将其拆成一个字符串的形式,通过空格隔开各个类名
|
|
77
75
|
//#ifdef MP-ALIPAY || MP-TOUTIAO || MP-BAIDU
|
|
78
|
-
classes = classes.join(
|
|
76
|
+
classes = classes.join(' ')
|
|
79
77
|
//#endif
|
|
80
|
-
return classes
|
|
81
|
-
})
|
|
78
|
+
return classes
|
|
79
|
+
})
|
|
82
80
|
const iconStyle = computed<CSSProperties>(() => {
|
|
83
|
-
let style: CSSProperties = {}
|
|
81
|
+
let style: CSSProperties = {}
|
|
84
82
|
style = {
|
|
85
83
|
fontSize: addUnit(size.value),
|
|
86
84
|
lineHeight: addUnit(size.value),
|
|
87
|
-
fontWeight: bold.value ?
|
|
85
|
+
fontWeight: bold.value ? 'bold' : 'normal',
|
|
88
86
|
// 某些特殊情况需要设置一个到顶部的距离,才能更好的垂直居中
|
|
89
87
|
top: addUnit(top.value),
|
|
90
88
|
borderRadius: addUnit(round.value),
|
|
91
89
|
color: color.value,
|
|
92
|
-
}
|
|
90
|
+
}
|
|
93
91
|
|
|
94
|
-
return style
|
|
95
|
-
})
|
|
92
|
+
return style
|
|
93
|
+
})
|
|
96
94
|
|
|
97
95
|
/**
|
|
98
96
|
* @description 判断传入的name属性,是否图片路径,只要带有"/"均认为是图片形式
|
|
99
97
|
* */
|
|
100
98
|
const isImg = computed(() => {
|
|
101
|
-
return name.value.indexOf(
|
|
102
|
-
})
|
|
99
|
+
return name.value.indexOf('/') !== -1
|
|
100
|
+
})
|
|
103
101
|
const imgStyle = computed((): CSSProperties => {
|
|
104
|
-
let style: CSSProperties = {}
|
|
102
|
+
let style: CSSProperties = {}
|
|
105
103
|
// 如果设置width和height属性,则优先使用,否则使用size属性
|
|
106
|
-
style.width = width.value ? addUnit(width.value) : addUnit(size.value)
|
|
107
|
-
style.height = height.value ? addUnit(height.value) : addUnit(size.value)
|
|
108
|
-
style.borderRadius = addUnit(round.value)
|
|
109
|
-
return style
|
|
110
|
-
})
|
|
104
|
+
style.width = width.value ? addUnit(width.value) : addUnit(size.value)
|
|
105
|
+
style.height = height.value ? addUnit(height.value) : addUnit(size.value)
|
|
106
|
+
style.borderRadius = addUnit(round.value)
|
|
107
|
+
return style
|
|
108
|
+
})
|
|
111
109
|
|
|
112
110
|
/**
|
|
113
111
|
* @description 点击
|
|
114
112
|
* */
|
|
115
113
|
const clickHandler = (e: any) => {
|
|
116
|
-
emit(
|
|
114
|
+
emit('click', index.value, e)
|
|
117
115
|
// 是否阻止事件冒泡
|
|
118
|
-
stop.value && e.stopPropagation()
|
|
119
|
-
}
|
|
116
|
+
stop.value && e.stopPropagation()
|
|
117
|
+
}
|
|
120
118
|
</script>
|
|
121
119
|
|
|
122
120
|
<style lang="scss" scoped>
|
|
123
|
-
@import
|
|
121
|
+
@import './index.scss';
|
|
124
122
|
</style>
|
|
@@ -1,24 +1,25 @@
|
|
|
1
|
-
import type IProps from
|
|
1
|
+
import type IProps from './typing'
|
|
2
2
|
|
|
3
3
|
const defaultProps: IProps = {
|
|
4
|
-
name:
|
|
5
|
-
color:
|
|
6
|
-
size:
|
|
4
|
+
name: '',
|
|
5
|
+
color: '',
|
|
6
|
+
size: '20px',
|
|
7
7
|
bold: false,
|
|
8
|
-
index:
|
|
9
|
-
customPrefix:
|
|
10
|
-
label:
|
|
11
|
-
labelPos:
|
|
12
|
-
labelSize:
|
|
13
|
-
labelColor:
|
|
14
|
-
space:
|
|
15
|
-
imgMode:
|
|
16
|
-
width:
|
|
17
|
-
height:
|
|
8
|
+
index: '',
|
|
9
|
+
customPrefix: 'hy-icon',
|
|
10
|
+
label: '',
|
|
11
|
+
labelPos: 'right',
|
|
12
|
+
labelSize: '',
|
|
13
|
+
labelColor: '',
|
|
14
|
+
space: '2px',
|
|
15
|
+
imgMode: '',
|
|
16
|
+
width: '',
|
|
17
|
+
height: '',
|
|
18
18
|
top: 0,
|
|
19
19
|
stop: false,
|
|
20
20
|
isRotate: false,
|
|
21
21
|
round: 0,
|
|
22
|
-
|
|
22
|
+
customClass: '',
|
|
23
|
+
}
|
|
23
24
|
|
|
24
|
-
export default defaultProps
|
|
25
|
+
export default defaultProps
|