@hlw-uni/mp-vue 1.0.3 → 1.0.5
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/dist/components/hlw-menu-list/{index.d.ts → types.d.ts} +0 -2
- package/dist/index.d.ts +8 -4
- package/dist/index.js +301 -113
- package/dist/index.mjs +302 -114
- package/dist/style.css +199 -0
- package/package.json +4 -2
- package/src/components/hlw-avatar/index.vue +64 -3
- package/src/components/hlw-card/index.vue +61 -0
- package/src/components/hlw-empty/index.vue +40 -3
- package/src/components/hlw-header/index.vue +138 -0
- package/src/components/hlw-loading/index.vue +40 -3
- package/src/components/hlw-menu-list/index.vue +93 -3
- package/src/components/hlw-menu-list/types.ts +8 -0
- package/src/components/hlw-page/index.vue +64 -0
- package/src/index.ts +8 -4
- package/dist/components/hlw-avatar/index.d.ts +0 -7
- package/dist/components/hlw-empty/index.d.ts +0 -2
- package/dist/components/hlw-loading/index.d.ts +0 -2
- package/src/components/hlw-avatar/index.ts +0 -52
- package/src/components/hlw-empty/index.ts +0 -34
- package/src/components/hlw-loading/index.ts +0 -29
- package/src/components/hlw-menu-list/index.ts +0 -64
|
@@ -1,4 +1,65 @@
|
|
|
1
|
-
<
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
<template>
|
|
2
|
+
<view :class="`hlw-avatar hlw-avatar--${size ?? 'medium'}`">
|
|
3
|
+
<image
|
|
4
|
+
v-if="src && !loadError"
|
|
5
|
+
class="hlw-avatar__image"
|
|
6
|
+
:src="src"
|
|
7
|
+
mode="aspectFill"
|
|
8
|
+
@error="loadError = true"
|
|
9
|
+
/>
|
|
10
|
+
<view v-else class="hlw-avatar__placeholder">
|
|
11
|
+
<text class="hlw-avatar__initial">{{ initial }}</text>
|
|
12
|
+
</view>
|
|
13
|
+
</view>
|
|
14
|
+
</template>
|
|
15
|
+
|
|
16
|
+
<script setup lang="ts">
|
|
17
|
+
import { ref, computed } from 'vue';
|
|
18
|
+
|
|
19
|
+
const props = defineProps<{
|
|
20
|
+
src?: string;
|
|
21
|
+
name?: string;
|
|
22
|
+
size?: 'small' | 'medium' | 'large';
|
|
23
|
+
}>();
|
|
24
|
+
|
|
25
|
+
const loadError = ref(false);
|
|
26
|
+
const initial = computed(() => {
|
|
27
|
+
if (!props.name) return '?';
|
|
28
|
+
return props.name.charAt(0).toUpperCase();
|
|
29
|
+
});
|
|
4
30
|
</script>
|
|
31
|
+
|
|
32
|
+
<style scoped>
|
|
33
|
+
.hlw-avatar {
|
|
34
|
+
border-radius: 50%;
|
|
35
|
+
overflow: hidden;
|
|
36
|
+
flex-shrink: 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.hlw-avatar--small { width: 56rpx; height: 56rpx; }
|
|
40
|
+
.hlw-avatar--medium { width: 80rpx; height: 80rpx; }
|
|
41
|
+
.hlw-avatar--large { width: 120rpx; height: 120rpx; }
|
|
42
|
+
|
|
43
|
+
.hlw-avatar__image {
|
|
44
|
+
width: 100%;
|
|
45
|
+
height: 100%;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.hlw-avatar__placeholder {
|
|
49
|
+
width: 100%;
|
|
50
|
+
height: 100%;
|
|
51
|
+
background: #07c160;
|
|
52
|
+
display: flex;
|
|
53
|
+
align-items: center;
|
|
54
|
+
justify-content: center;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.hlw-avatar__initial {
|
|
58
|
+
color: #fff;
|
|
59
|
+
font-weight: bold;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.hlw-avatar--small .hlw-avatar__initial { font-size: 22rpx; }
|
|
63
|
+
.hlw-avatar--medium .hlw-avatar__initial { font-size: 30rpx; }
|
|
64
|
+
.hlw-avatar--large .hlw-avatar__initial { font-size: 46rpx; }
|
|
65
|
+
</style>
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view class="hlw-card">
|
|
3
|
+
<view
|
|
4
|
+
v-if="$slots.header || title || icon || $slots['header-left'] || $slots['header-right']"
|
|
5
|
+
class="hlw-card-header"
|
|
6
|
+
>
|
|
7
|
+
<slot name="header">
|
|
8
|
+
<view class="flex items-center justify-between px-5 py-4 border-0 border-b border-dashed border-slate-200 bg-slate-50/30">
|
|
9
|
+
<view v-if="$slots['header-left'] || title || icon">
|
|
10
|
+
<slot name="header-left">
|
|
11
|
+
<view class="text-sm font-bold text-slate-800 flex items-center gap-2 tracking-wide">
|
|
12
|
+
<text v-if="icon" :class="[icon, iconColor]"></text>
|
|
13
|
+
<text>{{ title }}</text>
|
|
14
|
+
</view>
|
|
15
|
+
</slot>
|
|
16
|
+
</view>
|
|
17
|
+
<view v-if="$slots['header-right'] || extra">
|
|
18
|
+
<slot name="header-right">
|
|
19
|
+
<text
|
|
20
|
+
v-if="extra"
|
|
21
|
+
class="text-[10px] text-slate-400 bg-slate-50 px-2 py-1 rounded border border-slate-100 tracking-wide"
|
|
22
|
+
>{{ extra }}</text>
|
|
23
|
+
</slot>
|
|
24
|
+
</view>
|
|
25
|
+
</view>
|
|
26
|
+
</slot>
|
|
27
|
+
</view>
|
|
28
|
+
<view class="hlw-card-body">
|
|
29
|
+
<slot></slot>
|
|
30
|
+
</view>
|
|
31
|
+
</view>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<script setup lang="ts">
|
|
35
|
+
interface Props {
|
|
36
|
+
title?: string;
|
|
37
|
+
icon?: string;
|
|
38
|
+
iconColor?: string;
|
|
39
|
+
extra?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
withDefaults(defineProps<Props>(), {
|
|
43
|
+
title: '',
|
|
44
|
+
icon: '',
|
|
45
|
+
iconColor: '',
|
|
46
|
+
extra: '',
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
defineOptions({
|
|
50
|
+
options: {
|
|
51
|
+
styleIsolation: 'shared',
|
|
52
|
+
virtualHost: true,
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
</script>
|
|
56
|
+
|
|
57
|
+
<style scoped>
|
|
58
|
+
.hlw-card {
|
|
59
|
+
@apply bg-white rounded-xl border border-solid border-slate-200 overflow-hidden w-full;
|
|
60
|
+
}
|
|
61
|
+
</style>
|
|
@@ -1,4 +1,41 @@
|
|
|
1
|
-
<
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
<template>
|
|
2
|
+
<view class="hlw-empty">
|
|
3
|
+
<image v-if="image" class="hlw-empty__image" :src="image" mode="aspectFit" />
|
|
4
|
+
<text v-else class="hlw-empty__icon">📦</text>
|
|
5
|
+
<text class="hlw-empty__text">{{ text || '暂无数据' }}</text>
|
|
6
|
+
<slot />
|
|
7
|
+
</view>
|
|
8
|
+
</template>
|
|
9
|
+
|
|
10
|
+
<script setup lang="ts">
|
|
11
|
+
defineProps<{
|
|
12
|
+
text?: string;
|
|
13
|
+
image?: string;
|
|
14
|
+
}>();
|
|
4
15
|
</script>
|
|
16
|
+
|
|
17
|
+
<style scoped>
|
|
18
|
+
.hlw-empty {
|
|
19
|
+
display: flex;
|
|
20
|
+
flex-direction: column;
|
|
21
|
+
align-items: center;
|
|
22
|
+
justify-content: center;
|
|
23
|
+
padding: 80rpx 40rpx;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.hlw-empty__image {
|
|
27
|
+
width: 200rpx;
|
|
28
|
+
height: 200rpx;
|
|
29
|
+
margin-bottom: 24rpx;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.hlw-empty__icon {
|
|
33
|
+
font-size: 100rpx;
|
|
34
|
+
margin-bottom: 20rpx;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.hlw-empty__text {
|
|
38
|
+
font-size: 28rpx;
|
|
39
|
+
color: #bbb;
|
|
40
|
+
}
|
|
41
|
+
</style>
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view class="hlw-header" :style="{ height: totalNavBarHeight + 'px' }">
|
|
3
|
+
<view class="header-bg-layer" :class="hasBgSlot ? '' : props.bgClass">
|
|
4
|
+
<slot v-if="!props.isBack" name="bg"></slot>
|
|
5
|
+
</view>
|
|
6
|
+
<view class="status-bar-spacer" :style="{ height: statusBarHeight + 'px' }"></view>
|
|
7
|
+
<view class="header-content-area" :style="{ height: NAV_BAR_CONTENT_HEIGHT + 'px' }">
|
|
8
|
+
<template v-if="props.isBack">
|
|
9
|
+
<view class="header-back" @click="handleBack">
|
|
10
|
+
<text class="iconfont icon-back"></text>
|
|
11
|
+
</view>
|
|
12
|
+
<view class="header-title">{{ props.title }}</view>
|
|
13
|
+
<view class="header-placeholder"></view>
|
|
14
|
+
</template>
|
|
15
|
+
<slot v-else>
|
|
16
|
+
<view v-if="props.title" class="header-title">{{ props.title }}</view>
|
|
17
|
+
</slot>
|
|
18
|
+
</view>
|
|
19
|
+
</view>
|
|
20
|
+
</template>
|
|
21
|
+
|
|
22
|
+
<script setup lang="ts">
|
|
23
|
+
import { ref, computed, useSlots } from 'vue';
|
|
24
|
+
|
|
25
|
+
const getNavBarContentHeight = (): number => {
|
|
26
|
+
try {
|
|
27
|
+
const menuInfo = uni.getMenuButtonBoundingClientRect?.();
|
|
28
|
+
if (!menuInfo) return 44;
|
|
29
|
+
const systemInfo = uni.getSystemInfoSync();
|
|
30
|
+
return (menuInfo.top - systemInfo.statusBarHeight!) * 2 + menuInfo.height;
|
|
31
|
+
} catch {
|
|
32
|
+
return 44;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const getStatusBarHeight = (): number => {
|
|
37
|
+
try {
|
|
38
|
+
const systemInfo = uni.getSystemInfoSync();
|
|
39
|
+
return systemInfo.statusBarHeight || 20;
|
|
40
|
+
} catch {
|
|
41
|
+
return 20;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const NAV_BAR_CONTENT_HEIGHT = getNavBarContentHeight();
|
|
46
|
+
|
|
47
|
+
interface Props {
|
|
48
|
+
extraHeight?: number;
|
|
49
|
+
bgClass?: string;
|
|
50
|
+
isBack?: boolean;
|
|
51
|
+
title?: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
55
|
+
extraHeight: 0,
|
|
56
|
+
bgClass: '',
|
|
57
|
+
isBack: false,
|
|
58
|
+
title: '',
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const emit = defineEmits<{
|
|
62
|
+
back: [];
|
|
63
|
+
}>();
|
|
64
|
+
|
|
65
|
+
const handleBack = () => {
|
|
66
|
+
emit('back');
|
|
67
|
+
uni.navigateBack({ delta: 1 });
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const slots = useSlots();
|
|
71
|
+
const hasBgSlot = computed(() => !props.isBack && !!slots.bg);
|
|
72
|
+
const statusBarHeight = ref(getStatusBarHeight());
|
|
73
|
+
const totalNavBarHeight = computed(() => statusBarHeight.value + NAV_BAR_CONTENT_HEIGHT + props.extraHeight);
|
|
74
|
+
</script>
|
|
75
|
+
|
|
76
|
+
<style lang="scss" scoped>
|
|
77
|
+
.hlw-header {
|
|
78
|
+
position: sticky;
|
|
79
|
+
top: 0;
|
|
80
|
+
z-index: 999;
|
|
81
|
+
display: flex;
|
|
82
|
+
flex-direction: column;
|
|
83
|
+
overflow: hidden;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.header-bg-layer {
|
|
87
|
+
position: absolute;
|
|
88
|
+
top: 0;
|
|
89
|
+
left: 0;
|
|
90
|
+
right: 0;
|
|
91
|
+
bottom: 0;
|
|
92
|
+
z-index: 0;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.status-bar-spacer {
|
|
96
|
+
flex-shrink: 0;
|
|
97
|
+
width: 100%;
|
|
98
|
+
position: relative;
|
|
99
|
+
z-index: 1;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.header-content-area {
|
|
103
|
+
flex-shrink: 0;
|
|
104
|
+
width: 100%;
|
|
105
|
+
display: flex;
|
|
106
|
+
align-items: center;
|
|
107
|
+
position: relative;
|
|
108
|
+
z-index: 1;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.header-back {
|
|
112
|
+
width: 88rpx;
|
|
113
|
+
height: 100%;
|
|
114
|
+
display: flex;
|
|
115
|
+
align-items: center;
|
|
116
|
+
justify-content: center;
|
|
117
|
+
flex-shrink: 0;
|
|
118
|
+
|
|
119
|
+
.iconfont {
|
|
120
|
+
font-size: 40rpx;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.header-title {
|
|
125
|
+
flex: 1;
|
|
126
|
+
text-align: center;
|
|
127
|
+
font-size: 28rpx;
|
|
128
|
+
font-weight: 500;
|
|
129
|
+
overflow: hidden;
|
|
130
|
+
text-overflow: ellipsis;
|
|
131
|
+
white-space: nowrap;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.header-placeholder {
|
|
135
|
+
width: 88rpx;
|
|
136
|
+
flex-shrink: 0;
|
|
137
|
+
}
|
|
138
|
+
</style>
|
|
@@ -1,4 +1,41 @@
|
|
|
1
|
-
<
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
<template>
|
|
2
|
+
<view class="hlw-loading">
|
|
3
|
+
<view class="hlw-loading__spinner" />
|
|
4
|
+
<text v-if="text" class="hlw-loading__text">{{ text }}</text>
|
|
5
|
+
</view>
|
|
6
|
+
</template>
|
|
7
|
+
|
|
8
|
+
<script setup lang="ts">
|
|
9
|
+
defineProps<{
|
|
10
|
+
text?: string;
|
|
11
|
+
}>();
|
|
4
12
|
</script>
|
|
13
|
+
|
|
14
|
+
<style scoped>
|
|
15
|
+
.hlw-loading {
|
|
16
|
+
display: flex;
|
|
17
|
+
flex-direction: column;
|
|
18
|
+
align-items: center;
|
|
19
|
+
justify-content: center;
|
|
20
|
+
padding: 24rpx;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.hlw-loading__spinner {
|
|
24
|
+
width: 56rpx;
|
|
25
|
+
height: 56rpx;
|
|
26
|
+
border: 6rpx solid #e8e8e8;
|
|
27
|
+
border-top-color: #07c160;
|
|
28
|
+
border-radius: 50%;
|
|
29
|
+
animation: hlw-spin 0.8s linear infinite;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@keyframes hlw-spin {
|
|
33
|
+
to { transform: rotate(360deg); }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.hlw-loading__text {
|
|
37
|
+
margin-top: 16rpx;
|
|
38
|
+
font-size: 26rpx;
|
|
39
|
+
color: #999;
|
|
40
|
+
}
|
|
41
|
+
</style>
|
|
@@ -1,4 +1,94 @@
|
|
|
1
|
-
<
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
<template>
|
|
2
|
+
<view class="hlw-menu-list">
|
|
3
|
+
<view
|
|
4
|
+
v-for="item in items"
|
|
5
|
+
:key="item.key"
|
|
6
|
+
class="hlw-menu-list__item"
|
|
7
|
+
@tap="onTap(item)"
|
|
8
|
+
>
|
|
9
|
+
<view class="hlw-menu-list__left">
|
|
10
|
+
<text v-if="item.icon" class="hlw-menu-list__icon">{{ item.icon }}</text>
|
|
11
|
+
<text class="hlw-menu-list__label">{{ item.label }}</text>
|
|
12
|
+
</view>
|
|
13
|
+
<view class="hlw-menu-list__right">
|
|
14
|
+
<text v-if="item.value" class="hlw-menu-list__value">{{ item.value }}</text>
|
|
15
|
+
<text class="hlw-menu-list__arrow">›</text>
|
|
16
|
+
</view>
|
|
17
|
+
</view>
|
|
18
|
+
</view>
|
|
19
|
+
</template>
|
|
20
|
+
|
|
21
|
+
<script setup lang="ts">
|
|
22
|
+
import type { MenuItem } from './types';
|
|
23
|
+
|
|
24
|
+
const props = defineProps<{
|
|
25
|
+
items: MenuItem[];
|
|
26
|
+
}>();
|
|
27
|
+
|
|
28
|
+
const emit = defineEmits<{
|
|
29
|
+
(e: 'click', item: MenuItem): void;
|
|
30
|
+
}>();
|
|
31
|
+
|
|
32
|
+
function onTap(item: MenuItem) {
|
|
33
|
+
if (item.url) {
|
|
34
|
+
uni.navigateTo({ url: item.url });
|
|
35
|
+
} else if (item.action) {
|
|
36
|
+
item.action();
|
|
37
|
+
}
|
|
38
|
+
emit('click', item);
|
|
39
|
+
}
|
|
4
40
|
</script>
|
|
41
|
+
|
|
42
|
+
<style scoped>
|
|
43
|
+
.hlw-menu-list {
|
|
44
|
+
background: #fff;
|
|
45
|
+
border-radius: 16rpx;
|
|
46
|
+
overflow: hidden;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.hlw-menu-list__item {
|
|
50
|
+
display: flex;
|
|
51
|
+
align-items: center;
|
|
52
|
+
justify-content: space-between;
|
|
53
|
+
padding: 28rpx 32rpx;
|
|
54
|
+
border-bottom: 1rpx solid #f5f5f5;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.hlw-menu-list__item:last-child {
|
|
58
|
+
border-bottom: none;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.hlw-menu-list__left {
|
|
62
|
+
display: flex;
|
|
63
|
+
align-items: center;
|
|
64
|
+
gap: 16rpx;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.hlw-menu-list__icon {
|
|
68
|
+
font-size: 36rpx;
|
|
69
|
+
width: 44rpx;
|
|
70
|
+
text-align: center;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.hlw-menu-list__label {
|
|
74
|
+
font-size: 30rpx;
|
|
75
|
+
color: #333;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.hlw-menu-list__right {
|
|
79
|
+
display: flex;
|
|
80
|
+
align-items: center;
|
|
81
|
+
gap: 8rpx;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.hlw-menu-list__value {
|
|
85
|
+
font-size: 28rpx;
|
|
86
|
+
color: #999;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.hlw-menu-list__arrow {
|
|
90
|
+
font-size: 36rpx;
|
|
91
|
+
color: #ccc;
|
|
92
|
+
line-height: 1;
|
|
93
|
+
}
|
|
94
|
+
</style>
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view class="hlw-page">
|
|
3
|
+
<view class="hlw-page-header">
|
|
4
|
+
<slot name="header">
|
|
5
|
+
<hlw-header
|
|
6
|
+
v-if="title || isBack"
|
|
7
|
+
:title="title"
|
|
8
|
+
:is-back="isBack"
|
|
9
|
+
:bg-class="bgClass"
|
|
10
|
+
/>
|
|
11
|
+
</slot>
|
|
12
|
+
</view>
|
|
13
|
+
<scroll-view
|
|
14
|
+
class="hlw-page-content"
|
|
15
|
+
:scroll-y="true"
|
|
16
|
+
:enable-flex="true"
|
|
17
|
+
:enhanced="true"
|
|
18
|
+
:show-scrollbar="true"
|
|
19
|
+
>
|
|
20
|
+
<slot></slot>
|
|
21
|
+
</scroll-view>
|
|
22
|
+
<view class="hlw-page-footer">
|
|
23
|
+
<slot name="footer"></slot>
|
|
24
|
+
</view>
|
|
25
|
+
</view>
|
|
26
|
+
</template>
|
|
27
|
+
|
|
28
|
+
<script setup lang="ts">
|
|
29
|
+
interface Props {
|
|
30
|
+
title?: string;
|
|
31
|
+
isBack?: boolean;
|
|
32
|
+
bgClass?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
withDefaults(defineProps<Props>(), {
|
|
36
|
+
title: '',
|
|
37
|
+
isBack: false,
|
|
38
|
+
bgClass: '',
|
|
39
|
+
});
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<style lang="scss" scoped>
|
|
43
|
+
.hlw-page {
|
|
44
|
+
width: 100%;
|
|
45
|
+
height: 100vh;
|
|
46
|
+
display: flex;
|
|
47
|
+
flex-direction: column;
|
|
48
|
+
overflow: hidden;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.hlw-page-header {
|
|
52
|
+
flex-shrink: 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.hlw-page-content {
|
|
56
|
+
flex: 1;
|
|
57
|
+
height: 0;
|
|
58
|
+
width: 100%;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.hlw-page-footer {
|
|
62
|
+
flex-shrink: 0;
|
|
63
|
+
}
|
|
64
|
+
</style>
|
package/src/index.ts
CHANGED
|
@@ -3,7 +3,11 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
export { default as HlwAd } from './components/hlw-ad/index.vue';
|
|
6
|
-
export { default as HlwAvatar } from './components/hlw-avatar/index';
|
|
7
|
-
export { default as
|
|
8
|
-
export { default as
|
|
9
|
-
export { default as
|
|
6
|
+
export { default as HlwAvatar } from './components/hlw-avatar/index.vue';
|
|
7
|
+
export { default as HlwCard } from './components/hlw-card/index.vue';
|
|
8
|
+
export { default as HlwEmpty } from './components/hlw-empty/index.vue';
|
|
9
|
+
export { default as HlwHeader } from './components/hlw-header/index.vue';
|
|
10
|
+
export { default as HlwLoading } from './components/hlw-loading/index.vue';
|
|
11
|
+
export { default as HlwMenuList } from './components/hlw-menu-list/index.vue';
|
|
12
|
+
export { default as HlwPage } from './components/hlw-page/index.vue';
|
|
13
|
+
export type { MenuItem } from './components/hlw-menu-list/types';
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { defineComponent, ref, computed } from 'vue';
|
|
2
|
-
|
|
3
|
-
export interface AvatarProps {
|
|
4
|
-
src?: string;
|
|
5
|
-
name?: string;
|
|
6
|
-
size?: 'small' | 'medium' | 'large';
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export default defineComponent({
|
|
10
|
-
name: 'Avatar',
|
|
11
|
-
props: {
|
|
12
|
-
src: { type: String },
|
|
13
|
-
name: { type: String },
|
|
14
|
-
size: { type: String as () => 'small' | 'medium' | 'large', default: 'medium' },
|
|
15
|
-
},
|
|
16
|
-
setup(props) {
|
|
17
|
-
const loadError = ref(false);
|
|
18
|
-
|
|
19
|
-
const initial = computed(() => {
|
|
20
|
-
if (!props.name) return '?';
|
|
21
|
-
return props.name.charAt(0).toUpperCase();
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
function onError() { loadError.value = true; }
|
|
25
|
-
|
|
26
|
-
return () => {
|
|
27
|
-
const sizeClass = `hlw-avatar--${props.size}`;
|
|
28
|
-
return (
|
|
29
|
-
// @ts-ignore - uni app nodes
|
|
30
|
-
h('view', { class: `hlw-avatar ${sizeClass}` }, [
|
|
31
|
-
props.src && !loadError.value
|
|
32
|
-
? (
|
|
33
|
-
// @ts-ignore
|
|
34
|
-
h('image', {
|
|
35
|
-
class: 'hlw-avatar__image',
|
|
36
|
-
src: props.src,
|
|
37
|
-
mode: 'aspectFill',
|
|
38
|
-
onError,
|
|
39
|
-
})
|
|
40
|
-
)
|
|
41
|
-
: (
|
|
42
|
-
// @ts-ignore
|
|
43
|
-
h('view', { class: 'hlw-avatar__placeholder' }, [
|
|
44
|
-
// @ts-ignore
|
|
45
|
-
h('text', { class: 'hlw-avatar__initial' }, initial.value),
|
|
46
|
-
])
|
|
47
|
-
),
|
|
48
|
-
])
|
|
49
|
-
);
|
|
50
|
-
};
|
|
51
|
-
},
|
|
52
|
-
});
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { defineComponent, useSlots } from 'vue';
|
|
2
|
-
|
|
3
|
-
export default defineComponent({
|
|
4
|
-
name: 'Empty',
|
|
5
|
-
props: {
|
|
6
|
-
text: { type: String },
|
|
7
|
-
image: { type: String },
|
|
8
|
-
},
|
|
9
|
-
setup(props) {
|
|
10
|
-
const slots = useSlots();
|
|
11
|
-
return () => {
|
|
12
|
-
return (
|
|
13
|
-
// @ts-ignore
|
|
14
|
-
h('view', { class: 'hlw-empty' }, [
|
|
15
|
-
props.image
|
|
16
|
-
? (
|
|
17
|
-
// @ts-ignore
|
|
18
|
-
h('image', { class: 'hlw-empty__image', src: props.image, mode: 'aspectFit' })
|
|
19
|
-
)
|
|
20
|
-
: (
|
|
21
|
-
// @ts-ignore
|
|
22
|
-
h('view', { class: 'hlw-empty__icon' }, [
|
|
23
|
-
// @ts-ignore
|
|
24
|
-
h('text', '📦'),
|
|
25
|
-
])
|
|
26
|
-
),
|
|
27
|
-
// @ts-ignore
|
|
28
|
-
h('text', { class: 'hlw-empty__text' }, props.text || '暂无数据'),
|
|
29
|
-
slots.default?.(),
|
|
30
|
-
])
|
|
31
|
-
);
|
|
32
|
-
};
|
|
33
|
-
},
|
|
34
|
-
});
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { defineComponent } from 'vue';
|
|
2
|
-
|
|
3
|
-
export default defineComponent({
|
|
4
|
-
name: 'Loading',
|
|
5
|
-
props: {
|
|
6
|
-
text: { type: String },
|
|
7
|
-
},
|
|
8
|
-
setup(props) {
|
|
9
|
-
return () => {
|
|
10
|
-
const dots = Array.from({ length: 12 }, (_, i) =>
|
|
11
|
-
// @ts-ignore
|
|
12
|
-
h('view', { key: i + 1, class: 'hlw-loading__dot' }),
|
|
13
|
-
);
|
|
14
|
-
return (
|
|
15
|
-
// @ts-ignore
|
|
16
|
-
h('view', { class: 'hlw-loading' }, [
|
|
17
|
-
// @ts-ignore
|
|
18
|
-
h('view', { class: 'hlw-loading__spinner' }, dots),
|
|
19
|
-
props.text
|
|
20
|
-
? (
|
|
21
|
-
// @ts-ignore
|
|
22
|
-
h('text', { class: 'hlw-loading__text' }, props.text)
|
|
23
|
-
)
|
|
24
|
-
: null,
|
|
25
|
-
])
|
|
26
|
-
);
|
|
27
|
-
};
|
|
28
|
-
},
|
|
29
|
-
});
|