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
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
class="hy-transition"
|
|
5
5
|
ref="u-transition"
|
|
6
6
|
@tap.stop="clickHandler"
|
|
7
|
-
:class="classes"
|
|
7
|
+
:class="[classes, customClass]"
|
|
8
8
|
:style="[mergeStyle]"
|
|
9
9
|
>
|
|
10
10
|
<slot />
|
|
@@ -12,92 +12,85 @@
|
|
|
12
12
|
</template>
|
|
13
13
|
|
|
14
14
|
<script setup lang="ts">
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
watch,
|
|
20
|
-
nextTick,
|
|
21
|
-
toRefs,
|
|
22
|
-
} from "vue";
|
|
23
|
-
import { sleep } from "../../utils";
|
|
24
|
-
import defaultProps from "./props";
|
|
25
|
-
import type IProps from "./typing";
|
|
15
|
+
import { computed, type CSSProperties, ref, watch, nextTick, toRefs } from 'vue'
|
|
16
|
+
import { sleep } from '../../utils'
|
|
17
|
+
import defaultProps from './props'
|
|
18
|
+
import type IProps from './typing'
|
|
26
19
|
|
|
27
|
-
const props = withDefaults(defineProps<IProps>(), defaultProps)
|
|
28
|
-
const { show, mode, duration } = toRefs(props)
|
|
20
|
+
const props = withDefaults(defineProps<IProps>(), defaultProps)
|
|
21
|
+
const { show, mode, duration, customStyle, timingFunction } = toRefs(props)
|
|
29
22
|
const emit = defineEmits([
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
])
|
|
23
|
+
'click',
|
|
24
|
+
'beforeEnter',
|
|
25
|
+
'enter',
|
|
26
|
+
'afterEnter',
|
|
27
|
+
'beforeLeave',
|
|
28
|
+
'leave',
|
|
29
|
+
'afterLeave',
|
|
30
|
+
])
|
|
38
31
|
|
|
39
|
-
const hasInit = ref<boolean>(false)
|
|
40
|
-
const viewStyle = ref<CSSProperties>({})
|
|
41
|
-
const status = ref<string>(
|
|
42
|
-
const transitionEnded = ref<boolean>(false)
|
|
43
|
-
const display = ref<boolean>(false)
|
|
44
|
-
const classes = ref<string>(
|
|
32
|
+
const hasInit = ref<boolean>(false) // 是否显示/隐藏组件
|
|
33
|
+
const viewStyle = ref<CSSProperties>({}) // 组件内部的样式
|
|
34
|
+
const status = ref<string>('') // 记录组件动画的状态
|
|
35
|
+
const transitionEnded = ref<boolean>(false) // 组件是否结束的标记
|
|
36
|
+
const display = ref<boolean>(false) // 组件是否展示
|
|
37
|
+
const classes = ref<string>('') // 应用的类名
|
|
45
38
|
|
|
46
39
|
// #ifndef APP-NVUE
|
|
47
40
|
// 定义类名,通过给元素动态切换类名,赋予元素一定的css动画样式
|
|
48
41
|
const getClassNames = (name: string) => ({
|
|
49
42
|
enter: `u-${name}-enter u-${name}-enter-active`,
|
|
50
|
-
|
|
43
|
+
'enter-to': `u-${name}-enter-to u-${name}-enter-active`,
|
|
51
44
|
leave: `u-${name}-leave u-${name}-leave-active`,
|
|
52
|
-
|
|
53
|
-
})
|
|
45
|
+
'leave-to': `u-${name}-leave-to u-${name}-leave-active`,
|
|
46
|
+
})
|
|
54
47
|
// #endif
|
|
55
48
|
|
|
56
49
|
// #ifndef APP-NVUE
|
|
57
50
|
// vue版本的组件进场处理
|
|
58
51
|
const vueEnter = async () => {
|
|
59
52
|
// 动画进入时的类名
|
|
60
|
-
const classNames = getClassNames(mode.value)
|
|
53
|
+
const classNames = getClassNames(mode.value)
|
|
61
54
|
// 定义状态和发出动画进入前事件
|
|
62
|
-
status.value =
|
|
63
|
-
emit(
|
|
64
|
-
hasInit.value = true
|
|
65
|
-
display.value = true
|
|
66
|
-
classes.value = classNames.enter
|
|
67
|
-
await nextTick()
|
|
55
|
+
status.value = 'enter'
|
|
56
|
+
emit('beforeEnter')
|
|
57
|
+
hasInit.value = true
|
|
58
|
+
display.value = true
|
|
59
|
+
classes.value = classNames.enter
|
|
60
|
+
await nextTick()
|
|
68
61
|
{
|
|
69
62
|
// https://github.com/umicro/uView2.0/issues/545
|
|
70
|
-
await sleep(20)
|
|
63
|
+
await sleep(20)
|
|
71
64
|
// 标识动画尚未结束
|
|
72
|
-
emit(
|
|
73
|
-
transitionEnded.value = false
|
|
65
|
+
emit('enter')
|
|
66
|
+
transitionEnded.value = false
|
|
74
67
|
// 组件动画进入后触发的事件
|
|
75
|
-
emit(
|
|
68
|
+
emit('afterEnter')
|
|
76
69
|
// 赋予组件enter-to类名
|
|
77
|
-
classes.value = classNames[
|
|
70
|
+
classes.value = classNames['enter-to']
|
|
78
71
|
}
|
|
79
|
-
}
|
|
72
|
+
}
|
|
80
73
|
// 动画离场处理
|
|
81
74
|
const vueLeave = async () => {
|
|
82
75
|
// 如果不是展示状态,无需执行逻辑
|
|
83
|
-
if (!display.value) return
|
|
84
|
-
const classNames = getClassNames(mode.value)
|
|
76
|
+
if (!display.value) return
|
|
77
|
+
const classNames = getClassNames(mode.value)
|
|
85
78
|
// 标记离开状态和发出事件
|
|
86
|
-
status.value =
|
|
87
|
-
emit(
|
|
79
|
+
status.value = 'leave'
|
|
80
|
+
emit('beforeLeave')
|
|
88
81
|
// 获得类名
|
|
89
|
-
classes.value = classNames.leave
|
|
82
|
+
classes.value = classNames.leave
|
|
90
83
|
|
|
91
|
-
await nextTick()
|
|
84
|
+
await nextTick()
|
|
92
85
|
{
|
|
93
86
|
// 动画正在离场的状态
|
|
94
|
-
transitionEnded.value = false
|
|
95
|
-
emit(
|
|
87
|
+
transitionEnded.value = false
|
|
88
|
+
emit('leave')
|
|
96
89
|
// 组件执行动画,到了执行的执行时间后,执行一些额外处理
|
|
97
|
-
setTimeout(() => onTransitionEnd(), duration.value)
|
|
98
|
-
classes.value = classNames[
|
|
90
|
+
setTimeout(() => onTransitionEnd(), duration.value)
|
|
91
|
+
classes.value = classNames['leave-to']
|
|
99
92
|
}
|
|
100
|
-
}
|
|
93
|
+
}
|
|
101
94
|
// #endif
|
|
102
95
|
|
|
103
96
|
watch(
|
|
@@ -108,50 +101,49 @@ watch(
|
|
|
108
101
|
// newVal ? nvueEnter() : nvueLeave()
|
|
109
102
|
// #endif
|
|
110
103
|
// #ifndef APP-NVUE
|
|
111
|
-
newVal ? vueEnter() : vueLeave()
|
|
104
|
+
newVal ? vueEnter() : vueLeave()
|
|
112
105
|
// #endif
|
|
113
106
|
},
|
|
114
107
|
{ immediate: true },
|
|
115
|
-
)
|
|
108
|
+
)
|
|
116
109
|
|
|
117
110
|
const mergeStyle = computed(() => {
|
|
118
|
-
const { duration, customStyle, timingFunction } = props;
|
|
119
111
|
return {
|
|
120
112
|
// #ifndef APP-NVUE
|
|
121
|
-
transitionDuration: `${duration}ms`,
|
|
113
|
+
transitionDuration: `${duration.value}ms`,
|
|
122
114
|
// display: `${this.display ? '' : 'none'}`,
|
|
123
|
-
transitionTimingFunction: timingFunction,
|
|
115
|
+
transitionTimingFunction: timingFunction.value,
|
|
124
116
|
// #endif
|
|
125
117
|
// 避免自定义样式影响到动画属性,所以写在viewStyle前面
|
|
126
|
-
...customStyle,
|
|
118
|
+
...customStyle.value,
|
|
127
119
|
...viewStyle,
|
|
128
|
-
}
|
|
129
|
-
})
|
|
120
|
+
}
|
|
121
|
+
})
|
|
130
122
|
|
|
131
123
|
/**
|
|
132
124
|
* @description 组件被点击发出事件
|
|
133
125
|
* */
|
|
134
126
|
const clickHandler = () => {
|
|
135
|
-
emit(
|
|
136
|
-
}
|
|
127
|
+
emit('click')
|
|
128
|
+
}
|
|
137
129
|
|
|
138
130
|
const onTransitionEnd = () => {
|
|
139
131
|
// 如果已经是结束的状态,无需再处理
|
|
140
|
-
if (transitionEnded.value) return
|
|
141
|
-
transitionEnded.value = true
|
|
132
|
+
if (transitionEnded.value) return
|
|
133
|
+
transitionEnded.value = true
|
|
142
134
|
// 发出组件动画执行后的事件
|
|
143
|
-
emit(status.value ===
|
|
135
|
+
emit(status.value === 'leave' ? 'afterLeave' : 'afterEnter')
|
|
144
136
|
if (!show.value && display.value) {
|
|
145
|
-
display.value = false
|
|
146
|
-
hasInit.value = false
|
|
137
|
+
display.value = false
|
|
138
|
+
hasInit.value = false
|
|
147
139
|
}
|
|
148
|
-
}
|
|
140
|
+
}
|
|
149
141
|
</script>
|
|
150
142
|
|
|
151
143
|
<style lang="scss" scoped>
|
|
152
144
|
/* #ifndef APP-NVUE */
|
|
153
145
|
// vue版本动画相关的样式抽离在外部文件
|
|
154
|
-
@import
|
|
146
|
+
@import './index.scss';
|
|
155
147
|
/* #endif */
|
|
156
148
|
|
|
157
149
|
.hy-transition {
|
|
@@ -1,24 +1,28 @@
|
|
|
1
|
-
import type { CSSProperties } from
|
|
1
|
+
import type { CSSProperties } from 'vue'
|
|
2
2
|
|
|
3
3
|
export default interface HyTransitionProps {
|
|
4
4
|
/**
|
|
5
5
|
* @description 是否展示组件
|
|
6
6
|
* */
|
|
7
|
-
show: boolean
|
|
7
|
+
show: boolean
|
|
8
8
|
/**
|
|
9
9
|
* @description 使用的动画模式(默认:fade)
|
|
10
10
|
* */
|
|
11
|
-
mode?: HyApp.TransitionMode
|
|
11
|
+
mode?: HyApp.TransitionMode
|
|
12
12
|
/**
|
|
13
13
|
* @description 动画的执行时间,单位ms
|
|
14
14
|
* */
|
|
15
|
-
duration?: number
|
|
15
|
+
duration?: number
|
|
16
16
|
/**
|
|
17
17
|
* @description 使用的动画过渡函数(默认:ease-out)
|
|
18
18
|
* */
|
|
19
|
-
timingFunction?: string
|
|
19
|
+
timingFunction?: string
|
|
20
20
|
/**
|
|
21
21
|
* @description 定义需要用到的外部样式
|
|
22
22
|
* */
|
|
23
|
-
customStyle?: CSSProperties
|
|
23
|
+
customStyle?: CSSProperties
|
|
24
|
+
/**
|
|
25
|
+
* @description 定义组件的类名
|
|
26
|
+
* */
|
|
27
|
+
customClass?: string
|
|
24
28
|
}
|
package/composables/index.ts
CHANGED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { CSSProperties, getCurrentInstance, ref } from 'vue'
|
|
2
|
+
import { getRect, isObject } from '../utils'
|
|
3
|
+
import { IOffset, IPlacementVo } from '@/package/components/hy-popover/typing'
|
|
4
|
+
|
|
5
|
+
export function usePopover(visibleArrow = true) {
|
|
6
|
+
const { proxy } = getCurrentInstance() as any
|
|
7
|
+
const popStyle = ref<CSSProperties>()
|
|
8
|
+
const arrowStyle = ref<string>('')
|
|
9
|
+
const showStyle = ref<string>('')
|
|
10
|
+
const arrowClass = ref<string>('')
|
|
11
|
+
const popWidth = ref<number>(0)
|
|
12
|
+
const popHeight = ref<number>(0)
|
|
13
|
+
const left = ref<number>(0)
|
|
14
|
+
const bottom = ref<number>(0)
|
|
15
|
+
const width = ref<number>(0)
|
|
16
|
+
const height = ref<number>(0)
|
|
17
|
+
const top = ref<number>(0)
|
|
18
|
+
|
|
19
|
+
function noop() {}
|
|
20
|
+
|
|
21
|
+
function init(placement: IPlacementVo, visibleArrow: boolean, selector: string) {
|
|
22
|
+
// 初始化 class
|
|
23
|
+
if (visibleArrow) {
|
|
24
|
+
const arrowClassArr = [
|
|
25
|
+
`hy-${selector}__arrow`,
|
|
26
|
+
placement === 'bottom' || placement === 'bottom-start' || placement === 'bottom-end'
|
|
27
|
+
? `hy-${selector}__arrow-up`
|
|
28
|
+
: '',
|
|
29
|
+
placement === 'left' || placement === 'left-start' || placement === 'left-end'
|
|
30
|
+
? `hy-${selector}__arrow-right`
|
|
31
|
+
: '',
|
|
32
|
+
placement === 'right' || placement === 'right-start' || placement === 'right-end'
|
|
33
|
+
? `hy-${selector}__arrow-left`
|
|
34
|
+
: '',
|
|
35
|
+
placement === 'top' || placement === 'top-start' || placement === 'top-end'
|
|
36
|
+
? `hy-${selector}__arrow-down`
|
|
37
|
+
: '',
|
|
38
|
+
]
|
|
39
|
+
arrowClass.value = arrowClassArr.join(' ')
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// 初始化数据获取
|
|
43
|
+
getRect('#target', false, proxy).then((rect) => {
|
|
44
|
+
if (!rect) return
|
|
45
|
+
left.value = rect.left as number
|
|
46
|
+
bottom.value = rect.bottom as number
|
|
47
|
+
width.value = rect.width as number
|
|
48
|
+
height.value = rect.height as number
|
|
49
|
+
top.value = rect.top as number
|
|
50
|
+
})
|
|
51
|
+
// 用透明度可在初始化时获取到pop尺寸
|
|
52
|
+
getRect('#pos', false, proxy).then((rect) => {
|
|
53
|
+
if (!rect) return
|
|
54
|
+
popWidth.value = rect.width as number
|
|
55
|
+
popHeight.value = rect.height as number
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function control(placement: IPlacementVo, offset: IOffset) {
|
|
60
|
+
// arrow size
|
|
61
|
+
const arrowSize = visibleArrow ? 9 : 0
|
|
62
|
+
// 上下位(纵轴)对应的距离左边的距离
|
|
63
|
+
const verticalX = width.value / 2
|
|
64
|
+
// 上下位(纵轴)对应的距离底部的距离
|
|
65
|
+
const verticalY = arrowSize + height.value + 5
|
|
66
|
+
// 左右位(横轴)对应的距离左边的距离
|
|
67
|
+
const horizontalX = width.value + arrowSize + 5
|
|
68
|
+
// 左右位(横轴)对应的距离底部的距离
|
|
69
|
+
const horizontalY = height.value / 2
|
|
70
|
+
|
|
71
|
+
let offsetX = 0
|
|
72
|
+
let offsetY = 0
|
|
73
|
+
if (Array.isArray(offset)) {
|
|
74
|
+
offsetX = (verticalX - 17 > 0 ? 0 : verticalX - 25) + offset[0]
|
|
75
|
+
offsetY = (horizontalY - 17 > 0 ? 0 : horizontalY - 25) + (offset[1] ? offset[1] : offset[0])
|
|
76
|
+
} else if (isObject(offset)) {
|
|
77
|
+
offsetX = (verticalX - 17 > 0 ? 0 : verticalX - 25) + offset.x
|
|
78
|
+
offsetY = (horizontalY - 17 > 0 ? 0 : horizontalY - 25) + offset.y
|
|
79
|
+
} else {
|
|
80
|
+
offsetX = (verticalX - 17 > 0 ? 0 : verticalX - 25) + offset
|
|
81
|
+
offsetY = (horizontalY - 17 > 0 ? 0 : horizontalY - 25) + offset
|
|
82
|
+
}
|
|
83
|
+
// const offsetX = (verticalX - 17 > 0 ? 0 : verticalX - 25) + offset
|
|
84
|
+
// const offsetY = (horizontalY - 17 > 0 ? 0 : horizontalY - 25) + offset
|
|
85
|
+
|
|
86
|
+
const placements = new Map([
|
|
87
|
+
// 上
|
|
88
|
+
[
|
|
89
|
+
'top',
|
|
90
|
+
[
|
|
91
|
+
{
|
|
92
|
+
left: `${verticalX}px`,
|
|
93
|
+
bottom: `${verticalY}px`,
|
|
94
|
+
transform: 'translateX(-50%)',
|
|
95
|
+
},
|
|
96
|
+
'left: 50%;',
|
|
97
|
+
],
|
|
98
|
+
],
|
|
99
|
+
[
|
|
100
|
+
'top-start',
|
|
101
|
+
[
|
|
102
|
+
{
|
|
103
|
+
left: `${offsetX}px`,
|
|
104
|
+
bottom: `${verticalY}px`,
|
|
105
|
+
},
|
|
106
|
+
`left: ${(popWidth.value >= width.value ? width.value / 2 : popWidth.value - 25) - offsetX}px;`,
|
|
107
|
+
],
|
|
108
|
+
],
|
|
109
|
+
[
|
|
110
|
+
'top-end',
|
|
111
|
+
[
|
|
112
|
+
{
|
|
113
|
+
right: `${offsetX}px`,
|
|
114
|
+
bottom: `${verticalY}px`,
|
|
115
|
+
},
|
|
116
|
+
`right: ${(popWidth.value >= width.value ? width.value / 2 : popWidth.value - 25) - offsetX}px; transform: translateX(50%);`,
|
|
117
|
+
],
|
|
118
|
+
],
|
|
119
|
+
// 下
|
|
120
|
+
[
|
|
121
|
+
'bottom',
|
|
122
|
+
[
|
|
123
|
+
{
|
|
124
|
+
left: verticalX + 'px',
|
|
125
|
+
top: verticalY + 'px',
|
|
126
|
+
transform: 'translateX(-50%)',
|
|
127
|
+
},
|
|
128
|
+
'left: 50%;',
|
|
129
|
+
],
|
|
130
|
+
],
|
|
131
|
+
[
|
|
132
|
+
'bottom-start',
|
|
133
|
+
[
|
|
134
|
+
{
|
|
135
|
+
left: `${offsetX}px`,
|
|
136
|
+
top: `${verticalY}px`,
|
|
137
|
+
},
|
|
138
|
+
`left: ${(popWidth.value >= width.value ? width.value / 2 : popWidth.value - 25) - offsetX}px;`,
|
|
139
|
+
],
|
|
140
|
+
],
|
|
141
|
+
[
|
|
142
|
+
'bottom-end',
|
|
143
|
+
[
|
|
144
|
+
{
|
|
145
|
+
right: `${offsetX}px`,
|
|
146
|
+
top: `${verticalY}px`,
|
|
147
|
+
},
|
|
148
|
+
`right: ${(popWidth.value >= width.value ? width.value / 2 : popWidth.value - 25) - offsetX}px; transform: translateX(50%);`,
|
|
149
|
+
],
|
|
150
|
+
],
|
|
151
|
+
// 左
|
|
152
|
+
[
|
|
153
|
+
'left',
|
|
154
|
+
[
|
|
155
|
+
{
|
|
156
|
+
right: `${horizontalX}px`,
|
|
157
|
+
top: `${horizontalY}px`,
|
|
158
|
+
transform: 'translateY(-50%)',
|
|
159
|
+
},
|
|
160
|
+
'top: 50%',
|
|
161
|
+
],
|
|
162
|
+
],
|
|
163
|
+
[
|
|
164
|
+
'left-start',
|
|
165
|
+
[
|
|
166
|
+
{
|
|
167
|
+
right: `${horizontalX}px`,
|
|
168
|
+
top: `${offsetY}px`,
|
|
169
|
+
},
|
|
170
|
+
`top: ${(popHeight.value >= height.value ? height.value / 2 : popHeight.value - 20) - offsetY}px;`,
|
|
171
|
+
],
|
|
172
|
+
],
|
|
173
|
+
[
|
|
174
|
+
'left-end',
|
|
175
|
+
[
|
|
176
|
+
{
|
|
177
|
+
right: `${horizontalX}px`,
|
|
178
|
+
bottom: `${offsetY}px`,
|
|
179
|
+
},
|
|
180
|
+
`bottom: ${(popHeight.value >= height.value ? height.value / 2 : popHeight.value - 20) - offsetY}px; transform: translateY(50%);`,
|
|
181
|
+
],
|
|
182
|
+
],
|
|
183
|
+
// 右
|
|
184
|
+
[
|
|
185
|
+
'right',
|
|
186
|
+
[
|
|
187
|
+
{
|
|
188
|
+
left: `${horizontalX}px`,
|
|
189
|
+
top: `${horizontalY}px`,
|
|
190
|
+
transform: 'translateY(-50%)',
|
|
191
|
+
},
|
|
192
|
+
'top: 50%',
|
|
193
|
+
],
|
|
194
|
+
],
|
|
195
|
+
[
|
|
196
|
+
'right-start',
|
|
197
|
+
[
|
|
198
|
+
{
|
|
199
|
+
left: `${horizontalX}px`,
|
|
200
|
+
top: `${offsetY}px`,
|
|
201
|
+
},
|
|
202
|
+
`top: ${(popHeight.value >= height.value ? height.value / 2 : popHeight.value - 20) - offsetY}px;`,
|
|
203
|
+
],
|
|
204
|
+
],
|
|
205
|
+
[
|
|
206
|
+
'right-end',
|
|
207
|
+
[
|
|
208
|
+
{
|
|
209
|
+
left: `${horizontalX}px`,
|
|
210
|
+
bottom: `${offsetY}px`,
|
|
211
|
+
},
|
|
212
|
+
`bottom: ${(popHeight.value >= height.value ? height.value / 2 : popHeight.value - 20) - offsetY}px; transform: translateY(50%);`,
|
|
213
|
+
],
|
|
214
|
+
],
|
|
215
|
+
])
|
|
216
|
+
popStyle.value = placements.get(placement)![0] as CSSProperties
|
|
217
|
+
arrowStyle.value = placements.get(placement)![1] as string
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return { popStyle, arrowStyle, showStyle, arrowClass, init, control, noop }
|
|
221
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type Ref, provide, ref } from 'vue'
|
|
2
|
+
|
|
3
|
+
export const queueKey = '__QUEUE_KEY__'
|
|
4
|
+
|
|
5
|
+
export interface Queue {
|
|
6
|
+
queue: Ref<any[]>
|
|
7
|
+
pushToQueue: (comp: any) => void
|
|
8
|
+
removeFromQueue: (comp: any) => void
|
|
9
|
+
closeOther: (comp: any) => void
|
|
10
|
+
closeOutside: () => void
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function useQueue() {
|
|
14
|
+
const queue = ref<any[]>([])
|
|
15
|
+
|
|
16
|
+
function pushToQueue(comp: any) {
|
|
17
|
+
queue.value.push(comp)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function removeFromQueue(comp: any) {
|
|
21
|
+
queue.value = queue.value.filter((item) => {
|
|
22
|
+
return item.$.uid !== comp.$.uid
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function closeOther(comp: any) {
|
|
27
|
+
queue.value.forEach((item) => {
|
|
28
|
+
if (item.$.uid !== comp.$.uid) {
|
|
29
|
+
item.$.exposed.close()
|
|
30
|
+
}
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function closeOutside() {
|
|
35
|
+
queue.value.forEach((item) => {
|
|
36
|
+
item.$.exposed.close()
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
provide(queueKey, {
|
|
41
|
+
queue,
|
|
42
|
+
pushToQueue,
|
|
43
|
+
removeFromQueue,
|
|
44
|
+
closeOther,
|
|
45
|
+
closeOutside
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
closeOther,
|
|
50
|
+
closeOutside
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 辅助函数
|
|
3
|
+
*/
|
|
4
|
+
@import 'config';
|
|
5
|
+
$default-theme: #4d80f0 !default; // 正常色
|
|
6
|
+
|
|
7
|
+
/* 转换成字符串 */
|
|
8
|
+
@function selectorToString($selector) {
|
|
9
|
+
$selector: inspect($selector);
|
|
10
|
+
$selector: str-slice($selector, 2, -2);
|
|
11
|
+
|
|
12
|
+
@return $selector;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/* 判断是否存在 Modifier */
|
|
16
|
+
@function containsModifier($selector) {
|
|
17
|
+
$selector: selectorToString($selector);
|
|
18
|
+
|
|
19
|
+
@if str-index($selector, $modifierSeparator) {
|
|
20
|
+
@return true;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@else {
|
|
24
|
+
@return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/* 判断是否存在伪类 */
|
|
29
|
+
@function containsPseudo($selector) {
|
|
30
|
+
$selector: selectorToString($selector);
|
|
31
|
+
|
|
32
|
+
@if str-index($selector, ':') {
|
|
33
|
+
@return true;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@else {
|
|
37
|
+
@return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* 主题色切换
|
|
44
|
+
* @params $theme-color 主题色
|
|
45
|
+
* @params $type 变暗’dark‘ 变亮 'light'
|
|
46
|
+
* @params $mix-color 自己设置的混色
|
|
47
|
+
*/
|
|
48
|
+
@function themeColor($theme-color, $type: "", $mix-color: "") {
|
|
49
|
+
@if $default-theme !=#4d80f0 {
|
|
50
|
+
@if $type=="dark" {
|
|
51
|
+
@return darken($theme-color, 10%);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@else if $type=="light" {
|
|
55
|
+
@return lighten($theme-color, 10%);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@else {
|
|
59
|
+
@return $theme-color;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@else {
|
|
64
|
+
@return $mix-color;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* 颜色结果切换, 如果开启线性渐变色 使用渐变色,如果没有开启,那么使用主题色
|
|
70
|
+
* @params $open-linear 是否开启线性渐变色
|
|
71
|
+
* @params $deg 渐变色角度
|
|
72
|
+
* @params $theme-color 当前配色
|
|
73
|
+
* @params [Array] $set 主题色明暗设置,与 $color-list 数量对应
|
|
74
|
+
* @params [Array] $color-list 渐变色顺序, $color-list 和 $per-list 数量相同
|
|
75
|
+
* @params [Array] $per-list 渐变色比例
|
|
76
|
+
*/
|
|
77
|
+
@function resultColor($deg, $theme-color, $set, $color-list, $per-list) {
|
|
78
|
+
// 开启渐变
|
|
79
|
+
|
|
80
|
+
$len: length($color-list);
|
|
81
|
+
$arg: $deg;
|
|
82
|
+
|
|
83
|
+
@for $i from 1 through $len {
|
|
84
|
+
$arg: $arg + ","+ themeColor($theme-color, nth($set, $i), nth($color-list, $i)) + " "+ nth($per-list, $i);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@return linear-gradient(unquote($arg));
|
|
88
|
+
|
|
89
|
+
}
|