stellar-ui-plus 1.17.15 → 1.17.17
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/components/ste-progress/ATTRIBUTES.md +1 -0
- package/components/ste-progress/README.md +24 -11
- package/components/ste-progress/props.ts +20 -14
- package/components/ste-progress/ste-progress.easycom.json +6 -0
- package/components/ste-progress/ste-progress.vue +94 -16
- package/components/ste-select/ste-select.vue +6 -4
- package/components/ste-toast/ste-toast.vue +29 -12
- package/package.json +3 -2
- package/components/ste-toast/toast-bus.ts +0 -15
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
|
|
9
9
|
#### 背景色
|
|
10
10
|
|
|
11
|
-
-
|
|
12
|
-
-
|
|
11
|
+
- 背景色支持纯色、渐变色、图片
|
|
12
|
+
- 支持设置激活部分的背景(`activeBg`)和未激活部分(`inactiveBg`)的背景
|
|
13
13
|
|
|
14
14
|
```html
|
|
15
15
|
<ste-progress :percentage="40"></ste-progress>
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
#### 线条粗细
|
|
21
21
|
|
|
22
|
-
-
|
|
22
|
+
- 通过`strokeWidth`设置线条的粗细
|
|
23
23
|
|
|
24
24
|
```html
|
|
25
25
|
<ste-progress :percentage="40" strokeWidth="20"></ste-progress>
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
|
|
35
35
|
#### 长度
|
|
36
36
|
|
|
37
|
-
-
|
|
38
|
-
-
|
|
37
|
+
- 通过`width`设置进度条长度
|
|
38
|
+
- 默认是`100%`,跟随父容器的宽度
|
|
39
39
|
|
|
40
40
|
```html
|
|
41
41
|
<ste-progress :percentage="40" width="80%"></ste-progress>
|
|
@@ -50,10 +50,10 @@
|
|
|
50
50
|
|
|
51
51
|
#### 自定义文字内容
|
|
52
52
|
|
|
53
|
-
-
|
|
54
|
-
-
|
|
55
|
-
-
|
|
56
|
-
-
|
|
53
|
+
- 通过`pivotText`属性来自定义进度条内文字显示的内容
|
|
54
|
+
- 通过`textColor`属性来自定义进度条内文字的颜色
|
|
55
|
+
- 通过`textAlign`属性来自定义进度条内文字的对齐方式
|
|
56
|
+
- 通过`textSize`属性来自定义进度条内文字的大小
|
|
57
57
|
|
|
58
58
|
```html
|
|
59
59
|
<ste-progress :percentage="30" pivotText="已抢30%"></ste-progress>
|
|
@@ -64,14 +64,27 @@
|
|
|
64
64
|
|
|
65
65
|
#### 文本显示阈值
|
|
66
66
|
|
|
67
|
-
-
|
|
68
|
-
-
|
|
67
|
+
- 当进度条百分比(`percentage`)小于阈值时(`displayTextThreshold`),进度条的内容将不会显示
|
|
68
|
+
- 默认阈值是`0`,此时内容将始终显示
|
|
69
69
|
|
|
70
70
|
```html
|
|
71
71
|
<ste-progress :percentage="14" :displayTextThreshold="15"></ste-progress>
|
|
72
72
|
<ste-progress :percentage="35" :displayTextThreshold="15"></ste-progress>
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
+
#### 阶段配置
|
|
76
|
+
|
|
77
|
+
```html
|
|
78
|
+
<script lang="ts" setup>
|
|
79
|
+
const stageData = ref({
|
|
80
|
+
20: { label: '完成进度20%', style: { background: '#F53F3F' } },
|
|
81
|
+
50: { label: '完成进度50%', style: { background: '#FFC53D' } },
|
|
82
|
+
100: { label: '当月销售计划20,80万', style: { background: '#077EDB', textAlign: 'right' } },
|
|
83
|
+
});
|
|
84
|
+
</script>
|
|
85
|
+
<ste-progress :percentage="10" strokeWidth="36" :stageData="stageData"></ste-progress>
|
|
86
|
+
```
|
|
87
|
+
|
|
75
88
|
---$
|
|
76
89
|
|
|
77
90
|
### API
|
|
@@ -1,16 +1,22 @@
|
|
|
1
|
+
import type { PropType } from 'vue';
|
|
2
|
+
|
|
1
3
|
const progressProps = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
4
|
+
activeBg: { type: [String], default: '' },
|
|
5
|
+
inactiveBg: { type: [String], default: '#eeeeee' },
|
|
6
|
+
percentage: { type: [Number], default: 0 },
|
|
7
|
+
strokeWidth: { type: [String, Number], default: 24 },
|
|
8
|
+
disabled: { type: [Boolean], default: false },
|
|
9
|
+
width: { type: [String, Number], default: '100%' },
|
|
10
|
+
duration: { type: [Number], default: 0.3 },
|
|
11
|
+
pivotText: { type: [String], default: '' },
|
|
12
|
+
textColor: { type: [String], default: '#ffffff' },
|
|
13
|
+
textAlign: { type: [String], default: 'right' },
|
|
14
|
+
textSize: { type: [String, Number], default: 16 },
|
|
15
|
+
displayTextThreshold: { type: [Number], default: 0 },
|
|
16
|
+
stageData: {
|
|
17
|
+
type: Object as PropType<Record<string | number, any>>,
|
|
18
|
+
default: () => ({}),
|
|
19
|
+
},
|
|
20
|
+
};
|
|
15
21
|
|
|
16
|
-
export default progressProps
|
|
22
|
+
export default progressProps;
|
|
@@ -5,6 +5,8 @@ import utils from '../../utils/utils';
|
|
|
5
5
|
import { useColorStore } from '../../store/color';
|
|
6
6
|
let { getColor } = useColorStore();
|
|
7
7
|
|
|
8
|
+
let hasStage = false;
|
|
9
|
+
|
|
8
10
|
const slots = useSlots();
|
|
9
11
|
const props = defineProps(propsData);
|
|
10
12
|
|
|
@@ -18,20 +20,6 @@ onMounted(() => {
|
|
|
18
20
|
haveSlot.value = !!slots.default;
|
|
19
21
|
});
|
|
20
22
|
|
|
21
|
-
watch(
|
|
22
|
-
() => props.percentage,
|
|
23
|
-
val => {
|
|
24
|
-
if (val >= MAX) {
|
|
25
|
-
realPercentage.value = MAX;
|
|
26
|
-
} else if (val <= MIN) {
|
|
27
|
-
realPercentage.value = MIN;
|
|
28
|
-
} else {
|
|
29
|
-
realPercentage.value = val;
|
|
30
|
-
}
|
|
31
|
-
},
|
|
32
|
-
{ immediate: true }
|
|
33
|
-
);
|
|
34
|
-
|
|
35
23
|
const cmpRootCssVar = computed(() => {
|
|
36
24
|
let style: CSSProperties = {
|
|
37
25
|
'--progress-width': utils.addUnit(props.width),
|
|
@@ -83,12 +71,72 @@ const cmpActiveText = computed(() => {
|
|
|
83
71
|
}
|
|
84
72
|
return str;
|
|
85
73
|
});
|
|
74
|
+
|
|
75
|
+
const getPercentage = (value: number): number => {
|
|
76
|
+
if (!(typeof value === 'number')) {
|
|
77
|
+
return MIN;
|
|
78
|
+
}
|
|
79
|
+
if (value >= MAX) {
|
|
80
|
+
return MAX;
|
|
81
|
+
} else if (value <= MIN) {
|
|
82
|
+
return MIN;
|
|
83
|
+
} else {
|
|
84
|
+
return value;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const getStageStyle = (stageValue: number, index: number, value: any): CSSProperties => {
|
|
89
|
+
let style: CSSProperties = { width: `${getPercentage(stageValue)}%`, zIndex: Object.keys(props.stageData).length - index };
|
|
90
|
+
|
|
91
|
+
if (value instanceof Object && value.style) {
|
|
92
|
+
const { background, ...restStyle } = value.style;
|
|
93
|
+
style = {
|
|
94
|
+
...style,
|
|
95
|
+
...utils.bg2style(background),
|
|
96
|
+
...restStyle,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return style;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const getStageTextWidth = (index: number, value: any): CSSProperties => {
|
|
104
|
+
let style: CSSProperties = { width: '100%' };
|
|
105
|
+
if (index > 0) {
|
|
106
|
+
const stageValues = Object.keys(props.stageData);
|
|
107
|
+
const widthPercentage = (Number(stageValues[index]) - Number(stageValues[index - 1])) / Number(stageValues[index]);
|
|
108
|
+
style.width = `${widthPercentage * 100}%`;
|
|
109
|
+
style.textAlign = value.style?.textAlign;
|
|
110
|
+
}
|
|
111
|
+
return style;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
watch(
|
|
115
|
+
() => props.stageData,
|
|
116
|
+
val => {
|
|
117
|
+
hasStage = Object.keys(val || {}).length > 0;
|
|
118
|
+
},
|
|
119
|
+
{ immediate: true }
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
watch(
|
|
123
|
+
() => props.percentage,
|
|
124
|
+
val => {
|
|
125
|
+
realPercentage.value = getPercentage(val);
|
|
126
|
+
},
|
|
127
|
+
{ immediate: true }
|
|
128
|
+
);
|
|
86
129
|
</script>
|
|
87
130
|
|
|
88
131
|
<template>
|
|
89
132
|
<view class="ste-progress-root" :style="[cmpRootCssVar]">
|
|
90
133
|
<view class="inactive-box" :style="[cmpInactiveStyle]"></view>
|
|
91
|
-
<view class="
|
|
134
|
+
<view class="stage-box" v-if="hasStage">
|
|
135
|
+
<view class="stage" v-for="(item, index) in Object.keys(stageData)" :style="[getStageStyle(Number(item), index, stageData[item])]">
|
|
136
|
+
<text class="text" :style="[getStageTextWidth(index, stageData[item])]">{{ stageData[item].label }}</text>
|
|
137
|
+
</view>
|
|
138
|
+
</view>
|
|
139
|
+
<view class="active-box line" :style="[cmpActiveStyle]" v-if="realPercentage > 0 && !hasStage">
|
|
92
140
|
<slot v-if="haveSlot"></slot>
|
|
93
141
|
<text class="text" v-else>{{ cmpActiveText }}</text>
|
|
94
142
|
</view>
|
|
@@ -102,7 +150,9 @@ const cmpActiveText = computed(() => {
|
|
|
102
150
|
height: var(--progress-height);
|
|
103
151
|
|
|
104
152
|
> .inactive-box,
|
|
105
|
-
> .active-box
|
|
153
|
+
> .active-box,
|
|
154
|
+
> .stage-box,
|
|
155
|
+
> .stage-box > .stage {
|
|
106
156
|
width: var(--progress-width);
|
|
107
157
|
height: var(--progress-height);
|
|
108
158
|
border-radius: 24rpx;
|
|
@@ -131,5 +181,33 @@ const cmpActiveText = computed(() => {
|
|
|
131
181
|
line-height: 0;
|
|
132
182
|
}
|
|
133
183
|
}
|
|
184
|
+
|
|
185
|
+
.stage-box {
|
|
186
|
+
position: absolute;
|
|
187
|
+
left: 0;
|
|
188
|
+
top: 0;
|
|
189
|
+
|
|
190
|
+
.stage {
|
|
191
|
+
position: absolute;
|
|
192
|
+
left: 0;
|
|
193
|
+
top: 0;
|
|
194
|
+
|
|
195
|
+
text-align: right;
|
|
196
|
+
|
|
197
|
+
display: flex;
|
|
198
|
+
align-items: center;
|
|
199
|
+
justify-content: flex-end;
|
|
200
|
+
padding: var(--progress-padding) 0;
|
|
201
|
+
.text {
|
|
202
|
+
color: var(--active-text-color);
|
|
203
|
+
font-size: var(--active-text-font-size);
|
|
204
|
+
text-align: center;
|
|
205
|
+
|
|
206
|
+
overflow: hidden; //超出的文本隐藏
|
|
207
|
+
text-overflow: ellipsis; //溢出用省略号显示
|
|
208
|
+
white-space: nowrap; //溢出不换行
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
134
212
|
}
|
|
135
213
|
</style>
|
|
@@ -102,11 +102,13 @@ const loadMore = () => {
|
|
|
102
102
|
</scroll-view>
|
|
103
103
|
</slot>
|
|
104
104
|
<view class="open-icon-event" @click.stop="clickOpenIcon">
|
|
105
|
-
<
|
|
106
|
-
<view class="open-icon
|
|
107
|
-
<
|
|
105
|
+
<slot name="icon">
|
|
106
|
+
<view class="open-icon">
|
|
107
|
+
<view class="open-icon-transform">
|
|
108
|
+
<ste-icon code="" size="20" />
|
|
109
|
+
</view>
|
|
108
110
|
</view>
|
|
109
|
-
</
|
|
111
|
+
</slot>
|
|
110
112
|
</view>
|
|
111
113
|
|
|
112
114
|
<view class="clearable-icon" v-if="cmpShowClearable" @click.stop="clickClearable">
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { ref, computed, onUnmounted, onMounted } from 'vue';
|
|
3
|
-
import { toastState } from './toast-bus';
|
|
4
3
|
defineOptions({
|
|
5
4
|
name: 'ste-toast',
|
|
6
5
|
});
|
|
@@ -87,21 +86,39 @@ function hideToast() {
|
|
|
87
86
|
close.value();
|
|
88
87
|
}
|
|
89
88
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
showToast
|
|
94
|
-
|
|
89
|
+
const registEvent = (flag = true) => {
|
|
90
|
+
if (flag) {
|
|
91
|
+
// 注册事件
|
|
92
|
+
uni.$on('ste:toast:show', showToast);
|
|
93
|
+
uni.$on('ste:toast:hide', hideToast);
|
|
94
|
+
} else {
|
|
95
|
+
// 卸载事件
|
|
96
|
+
uni.$off('ste:toast:show');
|
|
97
|
+
uni.$off('ste:toast:hide');
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// 记录组件挂载时间
|
|
102
|
+
let mountTimestamp = 0;
|
|
103
|
+
// 最短合理的组件生命周期(毫秒)
|
|
104
|
+
// 用于解决APP等某些环境下组件卸载顺序异常,导致事件卸载
|
|
105
|
+
const MIN_REASONABLE_LIFECYCLE = 800;
|
|
95
106
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
107
|
+
onMounted(() => {
|
|
108
|
+
mountTimestamp = Date.now();
|
|
109
|
+
registEvent(false);
|
|
110
|
+
setTimeout(() => {
|
|
111
|
+
registEvent();
|
|
112
|
+
}, 200);
|
|
99
113
|
});
|
|
100
114
|
|
|
101
|
-
// 记得在组件卸载时移除事件监听
|
|
102
115
|
onUnmounted(() => {
|
|
103
|
-
|
|
104
|
-
|
|
116
|
+
// 计算组件生命周期时长
|
|
117
|
+
const lifecycleDuration = Date.now() - mountTimestamp;
|
|
118
|
+
// 只有当组件存活时间合理时,才考虑卸载事件监听
|
|
119
|
+
if (lifecycleDuration >= MIN_REASONABLE_LIFECYCLE) {
|
|
120
|
+
registEvent(false);
|
|
121
|
+
}
|
|
105
122
|
});
|
|
106
123
|
|
|
107
124
|
defineExpose({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stellar-ui-plus",
|
|
3
|
-
"version": "1.17.
|
|
3
|
+
"version": "1.17.17",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": "",
|
|
6
6
|
"license": "MIT",
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
13
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
14
|
-
"publish-vscode-plugin": "cd ../../../plugins/ste-helper & pnpm run publish"
|
|
14
|
+
"publish-vscode-plugin": "cd ../../../plugins/ste-helper & pnpm run publish",
|
|
15
|
+
"prepublishOnly": "pnpm run publish-vscode-plugin"
|
|
15
16
|
},
|
|
16
17
|
"dependencies": {
|
|
17
18
|
"dayjs": "^1.11.11"
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { ref } from 'vue';
|
|
2
|
-
|
|
3
|
-
export const toastState = ref({
|
|
4
|
-
show: false,
|
|
5
|
-
title: '',
|
|
6
|
-
icon: 'success',
|
|
7
|
-
image: '',
|
|
8
|
-
duration: 1500,
|
|
9
|
-
mask: false,
|
|
10
|
-
success: undefined,
|
|
11
|
-
fail: undefined,
|
|
12
|
-
complete: undefined,
|
|
13
|
-
close: undefined,
|
|
14
|
-
order: false,
|
|
15
|
-
});
|