hy-app 0.2.5 → 0.2.6
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 +62 -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-button/hy-button.vue +1 -1
- 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 +98 -10
- package/components/hy-float-button/props.ts +16 -14
- package/components/hy-float-button/typing.d.ts +34 -23
- package/components/hy-icon/hy-icon.vue +40 -42
- package/components/hy-icon/props.ts +17 -16
- package/components/hy-icon/typing.d.ts +24 -20
- 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-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-signature/props.ts +14 -14
- package/components/hy-tooltip/index.scss +2 -2
- package/libs/css/_config.scss +5 -0
- package/libs/css/_function.scss +89 -0
- package/libs/css/mixin.scss +58 -21
- package/libs/css/vars.css +3 -1
- package/package.json +2 -2
- package/theme.scss +2 -1
- package/utils/inspect.ts +48 -40
- package/utils/utils.ts +170 -187
|
@@ -1,89 +1,92 @@
|
|
|
1
|
-
import type { CSSProperties } from
|
|
2
|
-
import { HyApp } from
|
|
3
|
-
import type HyIconProps from
|
|
1
|
+
import type { CSSProperties } from 'vue'
|
|
2
|
+
import { HyApp } from '@/package/typing/modules/common'
|
|
3
|
+
import type HyIconProps from '../hy-icon/typing'
|
|
4
4
|
|
|
5
5
|
export interface CellContentVo extends AnyObject {
|
|
6
6
|
/**
|
|
7
7
|
* @description 单元格左图标
|
|
8
8
|
* */
|
|
9
|
-
icon?: Partial<HyIconProps
|
|
9
|
+
icon?: Partial<HyIconProps>
|
|
10
10
|
/**
|
|
11
11
|
* @description 单元格标题
|
|
12
12
|
* */
|
|
13
|
-
title?: string
|
|
13
|
+
title?: string
|
|
14
14
|
/**
|
|
15
15
|
* @description 单元格副标题
|
|
16
16
|
* */
|
|
17
|
-
subhead?: string
|
|
17
|
+
subhead?: string
|
|
18
18
|
/**
|
|
19
19
|
* @description 是否禁用单元格
|
|
20
20
|
* */
|
|
21
|
-
disabled?: boolean
|
|
21
|
+
disabled?: boolean
|
|
22
22
|
/**
|
|
23
23
|
* @description 单元格右图标集合
|
|
24
24
|
* */
|
|
25
|
-
rightIcon?: Partial<HyIconProps
|
|
25
|
+
rightIcon?: Partial<HyIconProps>
|
|
26
26
|
/**
|
|
27
27
|
* @description 单元格值
|
|
28
28
|
* */
|
|
29
|
-
value?: string
|
|
29
|
+
value?: string | number | boolean
|
|
30
30
|
/**
|
|
31
31
|
* @description 跳转页面地址
|
|
32
32
|
* */
|
|
33
|
-
url?: string
|
|
33
|
+
url?: string
|
|
34
34
|
/**
|
|
35
35
|
* @description 单元格右侧箭头的方向,可选值为:left,up,down,right
|
|
36
36
|
* */
|
|
37
|
-
arrowDirection?: HyApp.RotateType
|
|
37
|
+
arrowDirection?: HyApp.RotateType
|
|
38
38
|
}
|
|
39
39
|
export default interface HyCellProps {
|
|
40
40
|
/**
|
|
41
41
|
* @description cell列表数据
|
|
42
42
|
* */
|
|
43
|
-
list: CellContentVo[]
|
|
43
|
+
list: CellContentVo[]
|
|
44
44
|
/**
|
|
45
45
|
* @description 头部标题
|
|
46
46
|
* */
|
|
47
|
-
title?: string
|
|
47
|
+
title?: string
|
|
48
48
|
/**
|
|
49
49
|
* @description 是否显示标题前缀竖线
|
|
50
50
|
* */
|
|
51
|
-
showVertical?: boolean
|
|
51
|
+
showVertical?: boolean
|
|
52
52
|
/**
|
|
53
53
|
* @description 是否显示cell下边框 (默认 true )
|
|
54
54
|
* */
|
|
55
|
-
border?: boolean
|
|
56
|
-
|
|
55
|
+
border?: boolean
|
|
56
|
+
/**
|
|
57
|
+
* @description 圆角
|
|
58
|
+
* */
|
|
59
|
+
borderRadius?: string | number
|
|
57
60
|
/**
|
|
58
61
|
* @description 是否禁用cell(默认false)
|
|
59
62
|
* */
|
|
60
|
-
disabled?: boolean
|
|
63
|
+
disabled?: boolean
|
|
61
64
|
/**
|
|
62
65
|
* @description 是否开启点击反馈(表现为点击时加上灰色背景) (默认 false )
|
|
63
66
|
* */
|
|
64
|
-
clickable?: boolean
|
|
67
|
+
clickable?: boolean
|
|
65
68
|
/**
|
|
66
69
|
* @description 单元的大小,可选值为 large,medium,small
|
|
67
70
|
* */
|
|
68
|
-
size?: HyApp.SizeType
|
|
71
|
+
size?: HyApp.SizeType
|
|
69
72
|
/**
|
|
70
73
|
* @description 右侧的内容
|
|
71
74
|
* */
|
|
72
|
-
value?: string
|
|
75
|
+
value?: string
|
|
73
76
|
/**
|
|
74
77
|
* @description 内容是否垂直居中(主要是针对右侧的value部分) (默认 false )
|
|
75
78
|
* */
|
|
76
|
-
arrange?: HyApp.LeftRightType |
|
|
79
|
+
arrange?: HyApp.LeftRightType | 'center'
|
|
77
80
|
/**
|
|
78
81
|
* @description 右侧的图标箭头icon集合
|
|
79
82
|
* */
|
|
80
|
-
rightIcon?: Partial<HyIconProps
|
|
83
|
+
rightIcon?: Partial<HyIconProps>
|
|
81
84
|
/**
|
|
82
85
|
* @description 右侧箭头的方向,可选值为:left,up,down
|
|
83
86
|
* */
|
|
84
|
-
arrowDirection?:
|
|
87
|
+
arrowDirection?: 'left' | 'up' | 'down' | 'right'
|
|
85
88
|
/**
|
|
86
89
|
* @description 定义需要用到的外部样式
|
|
87
90
|
* */
|
|
88
|
-
customStyle?: CSSProperties
|
|
91
|
+
customStyle?: CSSProperties
|
|
89
92
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<view class="hy-empty" v-if="show" :style="emptyStyle">
|
|
3
3
|
<view class="hy-empty__img" :style="imgStyle">
|
|
4
4
|
<HyIcon
|
|
5
|
-
:name="imageUrl"
|
|
5
|
+
:name="imageUrl || emptyIcon[mode].icon"
|
|
6
6
|
:width="width"
|
|
7
7
|
:height="height"
|
|
8
8
|
img-mode="widthFix"
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
</view>
|
|
14
14
|
<view class="hy-empty__description" v-else>
|
|
15
15
|
<slot v-if="$slots.description" name="description"></slot>
|
|
16
|
-
<text v-else :style="descriptionStyle">{{ emptyDescription }}</text>
|
|
16
|
+
<text v-else :style="descriptionStyle">{{ emptyDescription || emptyIcon[mode].name }}</text>
|
|
17
17
|
<view class="hy-empty__button" v-if="button?.text">
|
|
18
18
|
<HyButton
|
|
19
19
|
:text="button?.text"
|
|
@@ -31,41 +31,34 @@
|
|
|
31
31
|
|
|
32
32
|
<script lang="ts">
|
|
33
33
|
export default {
|
|
34
|
-
name:
|
|
34
|
+
name: 'hy-empty',
|
|
35
35
|
options: {
|
|
36
36
|
addGlobalClass: true,
|
|
37
37
|
virtualHost: true,
|
|
38
|
-
styleIsolation:
|
|
38
|
+
styleIsolation: 'shared',
|
|
39
39
|
},
|
|
40
|
-
}
|
|
40
|
+
}
|
|
41
41
|
</script>
|
|
42
42
|
|
|
43
43
|
<script setup lang="ts">
|
|
44
|
-
import { computed, type CSSProperties, toRefs } from
|
|
45
|
-
import defaultProps from
|
|
46
|
-
import type IProps from
|
|
47
|
-
import { addUnit } from
|
|
44
|
+
import { computed, type CSSProperties, toRefs } from 'vue'
|
|
45
|
+
import defaultProps from './props'
|
|
46
|
+
import type IProps from './typing'
|
|
47
|
+
import { addUnit } from '../../utils'
|
|
48
|
+
import emptyIcon from './icon'
|
|
48
49
|
|
|
49
50
|
// 组件
|
|
50
|
-
import HyButton from
|
|
51
|
-
import HyIcon from
|
|
51
|
+
import HyButton from '../hy-button/hy-button.vue'
|
|
52
|
+
import HyIcon from '../hy-icon/hy-icon.vue'
|
|
52
53
|
|
|
53
|
-
const props = withDefaults(defineProps<IProps>(), defaultProps)
|
|
54
|
-
const {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
height,
|
|
58
|
-
imgMargin,
|
|
59
|
-
navigateUrl,
|
|
60
|
-
desSize,
|
|
61
|
-
desColor,
|
|
62
|
-
customStyle,
|
|
63
|
-
} = toRefs(props);
|
|
64
|
-
const emit = defineEmits(["click"]);
|
|
54
|
+
const props = withDefaults(defineProps<IProps>(), defaultProps)
|
|
55
|
+
const { zIndex, width, height, imgMargin, navigateUrl, desSize, desColor, customStyle } =
|
|
56
|
+
toRefs(props)
|
|
57
|
+
const emit = defineEmits(['click'])
|
|
65
58
|
|
|
66
59
|
const emptyDescription = computed(() => {
|
|
67
|
-
return props.description
|
|
68
|
-
})
|
|
60
|
+
return props.description
|
|
61
|
+
})
|
|
69
62
|
|
|
70
63
|
/**
|
|
71
64
|
* @description 整体样式
|
|
@@ -73,9 +66,9 @@ const emptyDescription = computed(() => {
|
|
|
73
66
|
const emptyStyle = computed<CSSProperties>(() => {
|
|
74
67
|
const style: CSSProperties = {
|
|
75
68
|
zIndex: zIndex.value,
|
|
76
|
-
}
|
|
77
|
-
return Object.assign(style, customStyle.value)
|
|
78
|
-
})
|
|
69
|
+
}
|
|
70
|
+
return Object.assign(style, customStyle.value)
|
|
71
|
+
})
|
|
79
72
|
|
|
80
73
|
/**
|
|
81
74
|
* @description 提示信息样式
|
|
@@ -84,9 +77,9 @@ const descriptionStyle = computed<CSSProperties>(() => {
|
|
|
84
77
|
const style: CSSProperties = {
|
|
85
78
|
fontSize: addUnit(desSize.value),
|
|
86
79
|
color: desColor.value,
|
|
87
|
-
}
|
|
88
|
-
return style
|
|
89
|
-
})
|
|
80
|
+
}
|
|
81
|
+
return style
|
|
82
|
+
})
|
|
90
83
|
|
|
91
84
|
/**
|
|
92
85
|
* @description 图片样式
|
|
@@ -96,21 +89,21 @@ const imgStyle = computed<CSSProperties>(() => {
|
|
|
96
89
|
width: addUnit(width.value),
|
|
97
90
|
height: addUnit(height.value),
|
|
98
91
|
margin: imgMargin.value,
|
|
99
|
-
}
|
|
100
|
-
})
|
|
92
|
+
}
|
|
93
|
+
})
|
|
101
94
|
|
|
102
95
|
/**
|
|
103
96
|
* @description 点击按钮,跳转页面
|
|
104
97
|
* */
|
|
105
98
|
const handleClick = () => {
|
|
106
|
-
emit(
|
|
99
|
+
emit('click')
|
|
107
100
|
if (navigateUrl.value) {
|
|
108
101
|
uni.navigateTo({
|
|
109
102
|
url: navigateUrl.value,
|
|
110
|
-
})
|
|
103
|
+
})
|
|
111
104
|
}
|
|
112
|
-
}
|
|
105
|
+
}
|
|
113
106
|
</script>
|
|
114
107
|
<style scoped lang="scss">
|
|
115
|
-
@import
|
|
108
|
+
@import './index.scss';
|
|
116
109
|
</style>
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
car: {
|
|
3
|
+
name: '购物车为空',
|
|
4
|
+
icon: 'https://pic1.imgdb.cn/item/685b54cb58cb8da5c86d0d4c.png',
|
|
5
|
+
},
|
|
6
|
+
page: {
|
|
7
|
+
name: '页面不存在',
|
|
8
|
+
icon: 'https://pic1.imgdb.cn/item/685a6b3f58cb8da5c86b6f64.webp',
|
|
9
|
+
},
|
|
10
|
+
search: {
|
|
11
|
+
name: '没有搜索结果',
|
|
12
|
+
icon: 'https://pic1.imgdb.cn/item/685a6b1f58cb8da5c86b6e84.webp',
|
|
13
|
+
},
|
|
14
|
+
address: {
|
|
15
|
+
name: '没有收货地址',
|
|
16
|
+
icon: 'https://pic1.imgdb.cn/item/685a6b3558cb8da5c86b6f1a.webp',
|
|
17
|
+
},
|
|
18
|
+
wifi: {
|
|
19
|
+
name: '没有网络',
|
|
20
|
+
icon: 'https://pic1.imgdb.cn/item/685a6b1f58cb8da5c86b6e87.webp',
|
|
21
|
+
},
|
|
22
|
+
order: {
|
|
23
|
+
name: '订单为空',
|
|
24
|
+
icon: 'https://pic1.imgdb.cn/item/685a6b1f58cb8da5c86b6e85.webp',
|
|
25
|
+
},
|
|
26
|
+
coupon: {
|
|
27
|
+
name: '没有优惠券',
|
|
28
|
+
icon: 'https://pic1.imgdb.cn/item/685a6b3f58cb8da5c86b6f63.webp',
|
|
29
|
+
},
|
|
30
|
+
favor: {
|
|
31
|
+
name: '暂无收藏',
|
|
32
|
+
icon: 'https://pic1.imgdb.cn/item/685a6b3558cb8da5c86b6f1b.webp',
|
|
33
|
+
},
|
|
34
|
+
permission: {
|
|
35
|
+
name: '无权限',
|
|
36
|
+
icon: 'https://pic1.imgdb.cn/item/685a6b4358cb8da5c86b6f85.webp',
|
|
37
|
+
},
|
|
38
|
+
history: {
|
|
39
|
+
name: '无历史记录',
|
|
40
|
+
icon: 'https://pic1.imgdb.cn/item/685a6b3f58cb8da5c86b6f62.webp',
|
|
41
|
+
},
|
|
42
|
+
message: {
|
|
43
|
+
name: '消息列表为空',
|
|
44
|
+
icon: 'https://pic1.imgdb.cn/item/685a6aef58cb8da5c86b6d30.webp',
|
|
45
|
+
},
|
|
46
|
+
image: {
|
|
47
|
+
name: '暂无图片',
|
|
48
|
+
icon: 'https://pic1.imgdb.cn/item/685a6b3f58cb8da5c86b6f65.webp',
|
|
49
|
+
},
|
|
50
|
+
video: {
|
|
51
|
+
name: '暂无视频',
|
|
52
|
+
icon: 'https://pic1.imgdb.cn/item/685a6b3f58cb8da5c86b6f66.webp',
|
|
53
|
+
},
|
|
54
|
+
comment: {
|
|
55
|
+
name: '暂无评论',
|
|
56
|
+
icon: 'https://pic1.imgdb.cn/item/685a6aef58cb8da5c86b6d30.webp',
|
|
57
|
+
},
|
|
58
|
+
integral: {
|
|
59
|
+
name: '暂无积分',
|
|
60
|
+
icon: 'https://pic1.imgdb.cn/item/685a6aef58cb8da5c86b6d2f.webp',
|
|
61
|
+
},
|
|
62
|
+
subscribe: {
|
|
63
|
+
name: '暂无预约',
|
|
64
|
+
icon: 'https://pic1.imgdb.cn/item/685a6b1f58cb8da5c86b6e86.webp',
|
|
65
|
+
},
|
|
66
|
+
earnings: {
|
|
67
|
+
name: '暂无收益',
|
|
68
|
+
icon: 'https://pic1.imgdb.cn/item/685a6b3558cb8da5c86b6f1c.webp',
|
|
69
|
+
},
|
|
70
|
+
announcement: {
|
|
71
|
+
name: '暂无公告',
|
|
72
|
+
icon: 'https://pic1.imgdb.cn/item/685a6b3558cb8da5c86b6f1d.webp',
|
|
73
|
+
},
|
|
74
|
+
signIn: {
|
|
75
|
+
name: '暂无打卡',
|
|
76
|
+
icon: 'https://pic1.imgdb.cn/item/685a6b1f58cb8da5c86b6e83.webp',
|
|
77
|
+
},
|
|
78
|
+
}
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import type IProps from
|
|
1
|
+
import type IProps from './typing'
|
|
2
2
|
|
|
3
3
|
const defaultProps: IProps = {
|
|
4
4
|
show: true,
|
|
5
|
-
|
|
5
|
+
mode: 'car',
|
|
6
|
+
imageUrl: '',
|
|
6
7
|
zIndex: 889,
|
|
7
8
|
width: 350,
|
|
8
|
-
height:
|
|
9
|
-
description:
|
|
9
|
+
height: 'auto',
|
|
10
|
+
description: '',
|
|
10
11
|
desSize: 15,
|
|
11
|
-
desColor:
|
|
12
|
-
imgMargin:
|
|
12
|
+
desColor: '',
|
|
13
|
+
imgMargin: '',
|
|
13
14
|
button: {},
|
|
14
|
-
navigateUrl:
|
|
15
|
-
}
|
|
15
|
+
navigateUrl: '',
|
|
16
|
+
}
|
|
16
17
|
|
|
17
|
-
export default defaultProps
|
|
18
|
+
export default defaultProps
|
|
@@ -1,53 +1,78 @@
|
|
|
1
|
-
import type { CSSProperties } from
|
|
2
|
-
import type HyButtonProps from
|
|
1
|
+
import type { CSSProperties } from 'vue'
|
|
2
|
+
import type HyButtonProps from '../hy-button/typing'
|
|
3
|
+
|
|
4
|
+
type EmptyModeType =
|
|
5
|
+
| 'car'
|
|
6
|
+
| 'page'
|
|
7
|
+
| 'search'
|
|
8
|
+
| 'address'
|
|
9
|
+
| 'wifi'
|
|
10
|
+
| 'order'
|
|
11
|
+
| 'coupon'
|
|
12
|
+
| 'favor'
|
|
13
|
+
| 'permission'
|
|
14
|
+
| 'history'
|
|
15
|
+
| 'message'
|
|
16
|
+
| 'image'
|
|
17
|
+
| 'video'
|
|
18
|
+
| 'comment'
|
|
19
|
+
| 'integral'
|
|
20
|
+
| 'subscribe'
|
|
21
|
+
| 'earnings'
|
|
22
|
+
| 'announcement'
|
|
23
|
+
| 'signIn'
|
|
3
24
|
|
|
4
25
|
export default interface HyEmptyProps {
|
|
5
26
|
/**
|
|
6
27
|
* @description 是否显示空状态
|
|
7
28
|
* */
|
|
8
|
-
show?: boolean
|
|
29
|
+
show?: boolean
|
|
30
|
+
/**
|
|
31
|
+
* @description 缺省页内容
|
|
32
|
+
* */
|
|
33
|
+
mode?: EmptyModeType
|
|
9
34
|
/**
|
|
10
35
|
* @description 空状态图片
|
|
11
36
|
* */
|
|
12
|
-
imageUrl?: string
|
|
37
|
+
imageUrl?: string
|
|
13
38
|
/**
|
|
14
39
|
* @description 组件层级
|
|
15
40
|
* */
|
|
16
|
-
zIndex?: number
|
|
41
|
+
zIndex?: number
|
|
17
42
|
/**
|
|
18
43
|
* @description icon宽度
|
|
19
44
|
* */
|
|
20
|
-
width?: number | string
|
|
45
|
+
width?: number | string
|
|
21
46
|
/**
|
|
22
47
|
* @description icon高度
|
|
23
48
|
* */
|
|
24
|
-
height?: number | string
|
|
49
|
+
height?: number | string
|
|
25
50
|
/**
|
|
26
51
|
* @description 提示信息
|
|
27
52
|
* */
|
|
28
|
-
description?: string
|
|
53
|
+
description?: string
|
|
29
54
|
/**
|
|
30
55
|
* @description 提示信息大小
|
|
31
56
|
* */
|
|
32
|
-
desSize?: string | number
|
|
57
|
+
desSize?: string | number
|
|
33
58
|
/**
|
|
34
59
|
* @description 提示信息颜色
|
|
35
60
|
* */
|
|
36
|
-
desColor?: string
|
|
61
|
+
desColor?: string
|
|
37
62
|
/**
|
|
38
63
|
* @description 图片margin
|
|
39
64
|
* */
|
|
40
|
-
imgMargin?: string
|
|
65
|
+
imgMargin?: string
|
|
41
66
|
/**
|
|
42
67
|
* @description 按钮属性只
|
|
43
68
|
* */
|
|
44
|
-
button?: HyButtonProps
|
|
69
|
+
button?: HyButtonProps
|
|
45
70
|
/**
|
|
46
71
|
* @description 跳转地址
|
|
47
72
|
* */
|
|
48
|
-
navigateUrl?: string
|
|
73
|
+
navigateUrl?: string
|
|
49
74
|
/**
|
|
50
75
|
* @description 自定义输入框外部样式
|
|
51
76
|
* */
|
|
52
|
-
customStyle?: CSSProperties
|
|
77
|
+
customStyle?: CSSProperties
|
|
53
78
|
}
|
|
@@ -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,7 @@ 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, getWindowInfo, guid } from '../../utils'
|
|
78
|
+
import { addUnit, getPx, getRect, getWindowInfo, guid, isH5 } from '../../utils'
|
|
76
79
|
|
|
77
80
|
// 组件
|
|
78
81
|
import HyIcon from '../hy-icon/hy-icon.vue'
|
|
@@ -82,8 +85,9 @@ const props = withDefaults(defineProps<IProps>(), defaultProps)
|
|
|
82
85
|
const {
|
|
83
86
|
menus,
|
|
84
87
|
customStyle,
|
|
88
|
+
gap,
|
|
85
89
|
left,
|
|
86
|
-
|
|
90
|
+
top,
|
|
87
91
|
zIndex,
|
|
88
92
|
bgColor,
|
|
89
93
|
text,
|
|
@@ -91,10 +95,12 @@ const {
|
|
|
91
95
|
size,
|
|
92
96
|
fixed,
|
|
93
97
|
direction,
|
|
98
|
+
draggable,
|
|
94
99
|
} = toRefs(props)
|
|
95
100
|
const emit = defineEmits(['click', 'clickItem'])
|
|
96
101
|
|
|
97
102
|
const instance = getCurrentInstance()
|
|
103
|
+
const { windowWidth } = getWindowInfo()
|
|
98
104
|
const btnSize: AnyObject = {
|
|
99
105
|
small: '50px',
|
|
100
106
|
medium: '60px',
|
|
@@ -104,6 +110,15 @@ const open = ref(false)
|
|
|
104
110
|
const rotate = computed(() => (open.value && !text.value ? '45deg' : '0deg'))
|
|
105
111
|
const soleId = `hy-float-button__${guid()}`
|
|
106
112
|
const showLeft = ref(false)
|
|
113
|
+
const fabSize = reactive({ width: 0, height: 0 }) // 悬浮按钮大小
|
|
114
|
+
const screen = reactive({ width: 0, height: 0 })
|
|
115
|
+
const currentCoordinate = reactive({
|
|
116
|
+
top: gap.value.top,
|
|
117
|
+
left: gap.value.left,
|
|
118
|
+
})
|
|
119
|
+
// 按下时坐标相对于元素的偏移量
|
|
120
|
+
const touchOffset = reactive({ x: 0, y: 0 })
|
|
121
|
+
const attractTransition = ref<boolean>(false)
|
|
107
122
|
|
|
108
123
|
/**
|
|
109
124
|
* @description 获取组件大小
|
|
@@ -121,11 +136,12 @@ const getFloatBtnSize = computed(() => {
|
|
|
121
136
|
* */
|
|
122
137
|
const FloatButtonStyle = computed(() => {
|
|
123
138
|
const style: CSSProperties = {
|
|
124
|
-
|
|
125
|
-
left: addUnit(left
|
|
139
|
+
top: addUnit(currentCoordinate.top),
|
|
140
|
+
left: addUnit(currentCoordinate.left),
|
|
126
141
|
backgroundColor: bgColor.value,
|
|
127
142
|
zIndex: zIndex.value,
|
|
128
143
|
color: textColor.value,
|
|
144
|
+
transition: 'all ease 0.3s',
|
|
129
145
|
}
|
|
130
146
|
if (fixed.value) style.position = 'fixed'
|
|
131
147
|
|
|
@@ -167,14 +183,26 @@ const menusStyle = computed(() => {
|
|
|
167
183
|
return style
|
|
168
184
|
})
|
|
169
185
|
|
|
170
|
-
onMounted(() => {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
const { left } = rect as UniApp.NodeInfo
|
|
174
|
-
if (left && left > windowWidth / 2) showLeft.value = true
|
|
175
|
-
})
|
|
186
|
+
onMounted(async () => {
|
|
187
|
+
await getFatRect()
|
|
188
|
+
getBounding()
|
|
176
189
|
})
|
|
177
190
|
|
|
191
|
+
/**
|
|
192
|
+
* @description 获取悬浮按钮大小
|
|
193
|
+
* */
|
|
194
|
+
const getFatRect = () => {
|
|
195
|
+
return new Promise((resolve, reject) => {
|
|
196
|
+
getRect(`#${soleId}`, false, instance).then((rect) => {
|
|
197
|
+
const { left, width, height } = rect as UniApp.NodeInfo
|
|
198
|
+
fabSize.width = width
|
|
199
|
+
fabSize.height = height
|
|
200
|
+
if (left && left > windowWidth / 2) showLeft.value = true
|
|
201
|
+
resolve(rect)
|
|
202
|
+
})
|
|
203
|
+
})
|
|
204
|
+
}
|
|
205
|
+
|
|
178
206
|
/**
|
|
179
207
|
* @description 点击悬浮按钮
|
|
180
208
|
* */
|
|
@@ -195,6 +223,66 @@ const handleMenuItemClick = (temp: MenusType, index: number) => {
|
|
|
195
223
|
})
|
|
196
224
|
}
|
|
197
225
|
}
|
|
226
|
+
|
|
227
|
+
const getBounding = () => {
|
|
228
|
+
const sysInfo = uni.getSystemInfoSync()
|
|
229
|
+
|
|
230
|
+
const { top = 16, left = 16, right = 16, bottom = 16 } = props.gap
|
|
231
|
+
screen.width = sysInfo.windowWidth
|
|
232
|
+
screen.height = isH5 ? sysInfo.windowTop + sysInfo.windowHeight : sysInfo.windowHeight
|
|
233
|
+
bounding.minTop = isH5 ? sysInfo.windowTop + top : top
|
|
234
|
+
bounding.minLeft = left
|
|
235
|
+
bounding.maxLeft = screen.width - fabSize.width - right
|
|
236
|
+
bounding.maxTop = screen.height - fabSize.height - bottom
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const bounding = {
|
|
240
|
+
minLeft: 10,
|
|
241
|
+
minTop: 10,
|
|
242
|
+
maxLeft: 380,
|
|
243
|
+
maxTop: 680,
|
|
244
|
+
}
|
|
245
|
+
const handleTouchStart = (e: TouchEvent) => {
|
|
246
|
+
if (!draggable.value) return
|
|
247
|
+
|
|
248
|
+
const touch = e.touches[0]
|
|
249
|
+
touchOffset.x = touch.clientX - getPx(currentCoordinate.left)
|
|
250
|
+
touchOffset.y = touch.clientY - getPx(currentCoordinate.top)
|
|
251
|
+
attractTransition.value = false
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function handleTouchMove(e: TouchEvent) {
|
|
255
|
+
if (!draggable.value) return
|
|
256
|
+
|
|
257
|
+
const touch = e.touches[0]
|
|
258
|
+
const { minLeft, minTop, maxLeft, maxTop } = bounding
|
|
259
|
+
let x = touch.clientX - touchOffset.x
|
|
260
|
+
let y = touch.clientY - touchOffset.y
|
|
261
|
+
|
|
262
|
+
if (x < minLeft) x = minLeft
|
|
263
|
+
else if (x > maxLeft) x = maxLeft
|
|
264
|
+
|
|
265
|
+
if (y < minTop) y = minTop
|
|
266
|
+
else if (y > maxTop) y = maxTop
|
|
267
|
+
|
|
268
|
+
currentCoordinate.top = y
|
|
269
|
+
currentCoordinate.left = x
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function handleTouchEnd() {
|
|
273
|
+
if (props.draggable === false) return
|
|
274
|
+
|
|
275
|
+
const screenCenterX = screen.width / 2
|
|
276
|
+
const fabCenterX = currentCoordinate.left + fabSize.width / 2
|
|
277
|
+
attractTransition.value = true
|
|
278
|
+
if (fabCenterX < screenCenterX) {
|
|
279
|
+
currentCoordinate.left = bounding.minLeft
|
|
280
|
+
// fabDirection.value = 'right'
|
|
281
|
+
} else {
|
|
282
|
+
currentCoordinate.left = bounding.maxLeft
|
|
283
|
+
// fabDirection.value = 'left'
|
|
284
|
+
}
|
|
285
|
+
}
|
|
198
286
|
</script>
|
|
199
287
|
|
|
200
288
|
<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
|
-
|
|
8
|
+
iconSize: '',
|
|
9
|
+
iconColor: '',
|
|
10
|
+
gap: { left: 16, right: 16 },
|
|
11
|
+
top: 80,
|
|
11
12
|
left: 20,
|
|
12
13
|
zIndex: 10086,
|
|
13
|
-
bgColor:
|
|
14
|
-
text:
|
|
15
|
-
fontSize:
|
|
16
|
-
textColor:
|
|
17
|
-
size:
|
|
18
|
-
shape:
|
|
14
|
+
bgColor: '',
|
|
15
|
+
text: '',
|
|
16
|
+
fontSize: '12px',
|
|
17
|
+
textColor: '',
|
|
18
|
+
size: 'medium',
|
|
19
|
+
shape: 'circle',
|
|
19
20
|
opacity: 1,
|
|
20
21
|
shadow: true,
|
|
21
22
|
float: true,
|
|
22
23
|
fixed: true,
|
|
23
|
-
|
|
24
|
+
draggable: true,
|
|
25
|
+
}
|
|
24
26
|
|
|
25
|
-
export default defaultProps
|
|
27
|
+
export default defaultProps
|