@atooyu/uxto-ui 1.0.7 → 1.0.9
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/index.js +66 -70
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +66 -70
- package/dist/index.mjs.map +1 -1
- package/dist/style.css +61 -62
- package/package.json +1 -1
- package/src/components/index.ts +50 -50
- package/src/components/u-link/u-link.vue +112 -112
- package/src/components/u-read-more/u-read-more.vue +116 -116
- package/src/components/u-skeleton/u-skeleton.vue +191 -191
- package/src/components/u-tabbar/u-tabbar.vue +3 -4
- package/src/components/u-transition/u-transition.vue +215 -215
|
@@ -1,117 +1,117 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<view class="u-read-more">
|
|
3
|
-
<view
|
|
4
|
-
class="u-read-more__content"
|
|
5
|
-
:style="contentStyle"
|
|
6
|
-
>
|
|
7
|
-
<slot />
|
|
8
|
-
</view>
|
|
9
|
-
<view
|
|
10
|
-
v-if="showToggle"
|
|
11
|
-
class="u-read-more__toggle"
|
|
12
|
-
@click="handleToggle"
|
|
13
|
-
>
|
|
14
|
-
<text class="u-read-more__toggle-text">{{ toggleText }}</text>
|
|
15
|
-
<text class="u-read-more__toggle-icon">{{ expanded ? '↑' : '↓' }}</text>
|
|
16
|
-
</view>
|
|
17
|
-
</view>
|
|
18
|
-
</template>
|
|
19
|
-
|
|
20
|
-
<script setup lang="ts">
|
|
21
|
-
import { computed, ref, watch } from 'vue'
|
|
22
|
-
|
|
23
|
-
interface Props {
|
|
24
|
-
maxLength?: number
|
|
25
|
-
rows?: number
|
|
26
|
-
expandText?: string
|
|
27
|
-
collapseText?: string
|
|
28
|
-
autoCollapse?: boolean
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const props = withDefaults(defineProps<Props>(), {
|
|
32
|
-
maxLength: 200,
|
|
33
|
-
rows: 3,
|
|
34
|
-
expandText: '展开',
|
|
35
|
-
collapseText: '收起',
|
|
36
|
-
autoCollapse: false
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
const emit = defineEmits<{
|
|
40
|
-
(e: 'expand'): void
|
|
41
|
-
(e: 'collapse'): void
|
|
42
|
-
}>()
|
|
43
|
-
|
|
44
|
-
const expanded = ref(false)
|
|
45
|
-
const showToggle = ref(true)
|
|
46
|
-
|
|
47
|
-
// 内容区域样式
|
|
48
|
-
const contentStyle = computed(() => {
|
|
49
|
-
if (expanded.value) {
|
|
50
|
-
return {}
|
|
51
|
-
}
|
|
52
|
-
// 使用 line-clamp 限制行数
|
|
53
|
-
return {
|
|
54
|
-
display: '-webkit-box',
|
|
55
|
-
overflow: 'hidden',
|
|
56
|
-
textOverflow: 'ellipsis',
|
|
57
|
-
webkitLineClamp: String(props.rows),
|
|
58
|
-
webkitBoxOrient: 'vertical'
|
|
59
|
-
}
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
// 切换按钮文字
|
|
63
|
-
const toggleText = computed(() => {
|
|
64
|
-
return expanded.value ? props.collapseText : props.expandText
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
// 切换展开/收起
|
|
68
|
-
const handleToggle = () => {
|
|
69
|
-
expanded.value = !expanded.value
|
|
70
|
-
|
|
71
|
-
if (expanded.value) {
|
|
72
|
-
emit('expand')
|
|
73
|
-
} else {
|
|
74
|
-
emit('collapse')
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
</script>
|
|
78
|
-
|
|
79
|
-
<script lang="ts">
|
|
80
|
-
export default {
|
|
81
|
-
options: {
|
|
82
|
-
virtualHost: true,
|
|
83
|
-
styleIsolation: 'shared'
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
</script>
|
|
87
|
-
|
|
88
|
-
<style lang="scss" scoped>
|
|
89
|
-
.u-read-more {
|
|
90
|
-
&__content {
|
|
91
|
-
font-size: $--font-size-md;
|
|
92
|
-
color: $--text-color;
|
|
93
|
-
line-height: 1.6;
|
|
94
|
-
word-break: break-all;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
&__toggle {
|
|
98
|
-
display: inline-flex;
|
|
99
|
-
align-items: center;
|
|
100
|
-
margin-top: $--spacing-sm;
|
|
101
|
-
color: $--color-primary;
|
|
102
|
-
font-size: $--font-size-md;
|
|
103
|
-
|
|
104
|
-
&:active {
|
|
105
|
-
opacity: 0.7;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
&__toggle-text {
|
|
110
|
-
margin-right: $--spacing-xs;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
&__toggle-icon {
|
|
114
|
-
font-size: $--font-size-sm;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
1
|
+
<template>
|
|
2
|
+
<view class="u-read-more">
|
|
3
|
+
<view
|
|
4
|
+
class="u-read-more__content"
|
|
5
|
+
:style="contentStyle"
|
|
6
|
+
>
|
|
7
|
+
<slot />
|
|
8
|
+
</view>
|
|
9
|
+
<view
|
|
10
|
+
v-if="showToggle"
|
|
11
|
+
class="u-read-more__toggle"
|
|
12
|
+
@click="handleToggle"
|
|
13
|
+
>
|
|
14
|
+
<text class="u-read-more__toggle-text">{{ toggleText }}</text>
|
|
15
|
+
<text class="u-read-more__toggle-icon">{{ expanded ? '↑' : '↓' }}</text>
|
|
16
|
+
</view>
|
|
17
|
+
</view>
|
|
18
|
+
</template>
|
|
19
|
+
|
|
20
|
+
<script setup lang="ts">
|
|
21
|
+
import { computed, ref, watch } from 'vue'
|
|
22
|
+
|
|
23
|
+
interface Props {
|
|
24
|
+
maxLength?: number
|
|
25
|
+
rows?: number
|
|
26
|
+
expandText?: string
|
|
27
|
+
collapseText?: string
|
|
28
|
+
autoCollapse?: boolean
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
32
|
+
maxLength: 200,
|
|
33
|
+
rows: 3,
|
|
34
|
+
expandText: '展开',
|
|
35
|
+
collapseText: '收起',
|
|
36
|
+
autoCollapse: false
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
const emit = defineEmits<{
|
|
40
|
+
(e: 'expand'): void
|
|
41
|
+
(e: 'collapse'): void
|
|
42
|
+
}>()
|
|
43
|
+
|
|
44
|
+
const expanded = ref(false)
|
|
45
|
+
const showToggle = ref(true)
|
|
46
|
+
|
|
47
|
+
// 内容区域样式
|
|
48
|
+
const contentStyle = computed(() => {
|
|
49
|
+
if (expanded.value) {
|
|
50
|
+
return {}
|
|
51
|
+
}
|
|
52
|
+
// 使用 line-clamp 限制行数
|
|
53
|
+
return {
|
|
54
|
+
display: '-webkit-box',
|
|
55
|
+
overflow: 'hidden',
|
|
56
|
+
textOverflow: 'ellipsis',
|
|
57
|
+
webkitLineClamp: String(props.rows),
|
|
58
|
+
webkitBoxOrient: 'vertical'
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
// 切换按钮文字
|
|
63
|
+
const toggleText = computed(() => {
|
|
64
|
+
return expanded.value ? props.collapseText : props.expandText
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
// 切换展开/收起
|
|
68
|
+
const handleToggle = () => {
|
|
69
|
+
expanded.value = !expanded.value
|
|
70
|
+
|
|
71
|
+
if (expanded.value) {
|
|
72
|
+
emit('expand')
|
|
73
|
+
} else {
|
|
74
|
+
emit('collapse')
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
</script>
|
|
78
|
+
|
|
79
|
+
<script lang="ts">
|
|
80
|
+
export default {
|
|
81
|
+
options: {
|
|
82
|
+
virtualHost: true,
|
|
83
|
+
styleIsolation: 'shared'
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
</script>
|
|
87
|
+
|
|
88
|
+
<style lang="scss" scoped>
|
|
89
|
+
.u-read-more {
|
|
90
|
+
&__content {
|
|
91
|
+
font-size: $--font-size-md;
|
|
92
|
+
color: $--text-color;
|
|
93
|
+
line-height: 1.6;
|
|
94
|
+
word-break: break-all;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
&__toggle {
|
|
98
|
+
display: inline-flex;
|
|
99
|
+
align-items: center;
|
|
100
|
+
margin-top: $--spacing-sm;
|
|
101
|
+
color: $--color-primary;
|
|
102
|
+
font-size: $--font-size-md;
|
|
103
|
+
|
|
104
|
+
&:active {
|
|
105
|
+
opacity: 0.7;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
&__toggle-text {
|
|
110
|
+
margin-right: $--spacing-xs;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
&__toggle-icon {
|
|
114
|
+
font-size: $--font-size-sm;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
117
|
</style>
|
|
@@ -1,192 +1,192 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<view v-if="!loading" class="u-skeleton__content">
|
|
3
|
-
<slot />
|
|
4
|
-
</view>
|
|
5
|
-
<view v-else class="u-skeleton" :class="{ 'u-skeleton--animate': animate }">
|
|
6
|
-
<!-- 头像骨架 -->
|
|
7
|
-
<view
|
|
8
|
-
v-if="avatar"
|
|
9
|
-
class="u-skeleton__avatar"
|
|
10
|
-
:class="`u-skeleton__avatar--${avatarShape}`"
|
|
11
|
-
:style="avatarStyle"
|
|
12
|
-
/>
|
|
13
|
-
<!-- 内容区域 -->
|
|
14
|
-
<view class="u-skeleton__content">
|
|
15
|
-
<!-- 标题骨架 -->
|
|
16
|
-
<view
|
|
17
|
-
v-if="title"
|
|
18
|
-
class="u-skeleton__title"
|
|
19
|
-
:style="titleStyle"
|
|
20
|
-
/>
|
|
21
|
-
<!-- 段落骨架 -->
|
|
22
|
-
<view class="u-skeleton__paragraphs">
|
|
23
|
-
<view
|
|
24
|
-
v-for="(row, index) in rowList"
|
|
25
|
-
:key="index"
|
|
26
|
-
class="u-skeleton__paragraph"
|
|
27
|
-
:style="getRowStyle(index)"
|
|
28
|
-
/>
|
|
29
|
-
</view>
|
|
30
|
-
</view>
|
|
31
|
-
</view>
|
|
32
|
-
</template>
|
|
33
|
-
|
|
34
|
-
<script setup lang="ts">
|
|
35
|
-
import { computed } from 'vue'
|
|
36
|
-
|
|
37
|
-
type AvatarShape = 'circle' | 'square'
|
|
38
|
-
type TitleWidth = number | string
|
|
39
|
-
|
|
40
|
-
interface Props {
|
|
41
|
-
loading?: boolean
|
|
42
|
-
animate?: boolean
|
|
43
|
-
avatar?: boolean
|
|
44
|
-
avatarSize?: number | string
|
|
45
|
-
avatarShape?: AvatarShape
|
|
46
|
-
title?: boolean
|
|
47
|
-
titleWidth?: TitleWidth
|
|
48
|
-
row?: number
|
|
49
|
-
rowWidth?: number | string | (number | string)[]
|
|
50
|
-
rowHeight?: number | string | (number | string)[]
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const props = withDefaults(defineProps<Props>(), {
|
|
54
|
-
loading: true,
|
|
55
|
-
animate: true,
|
|
56
|
-
avatar: false,
|
|
57
|
-
avatarSize: 40,
|
|
58
|
-
avatarShape: 'circle',
|
|
59
|
-
title: true,
|
|
60
|
-
titleWidth: '40%',
|
|
61
|
-
row: 3,
|
|
62
|
-
rowWidth: '100%',
|
|
63
|
-
rowHeight: 16
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
const avatarStyle = computed(() => {
|
|
67
|
-
const size = typeof props.avatarSize === 'number'
|
|
68
|
-
? `${props.avatarSize}px`
|
|
69
|
-
: props.avatarSize
|
|
70
|
-
return {
|
|
71
|
-
width: size,
|
|
72
|
-
height: size
|
|
73
|
-
}
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
const titleStyle = computed(() => {
|
|
77
|
-
const width = typeof props.titleWidth === 'number'
|
|
78
|
-
? `${props.titleWidth}px`
|
|
79
|
-
: props.titleWidth
|
|
80
|
-
return { width }
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
const rowList = computed(() => {
|
|
84
|
-
return Array.from({ length: props.row }, (_, i) => i)
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
const getRowStyle = (index: number) => {
|
|
88
|
-
const style: Record<string, string> = {}
|
|
89
|
-
|
|
90
|
-
// 处理宽度
|
|
91
|
-
if (Array.isArray(props.rowWidth)) {
|
|
92
|
-
const width = props.rowWidth[index]
|
|
93
|
-
if (width !== undefined) {
|
|
94
|
-
style.width = typeof width === 'number' ? `${width}px` : width
|
|
95
|
-
}
|
|
96
|
-
} else if (index === props.row - 1 && props.rowWidth === '100%') {
|
|
97
|
-
// 最后一行默认 60% 宽度(如果是 100% 才处理)
|
|
98
|
-
style.width = '60%'
|
|
99
|
-
} else {
|
|
100
|
-
style.width = typeof props.rowWidth === 'number'
|
|
101
|
-
? `${props.rowWidth}px`
|
|
102
|
-
: props.rowWidth
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// 处理高度
|
|
106
|
-
if (Array.isArray(props.rowHeight)) {
|
|
107
|
-
const height = props.rowHeight[index]
|
|
108
|
-
if (height !== undefined) {
|
|
109
|
-
style.height = typeof height === 'number' ? `${height}px` : height
|
|
110
|
-
}
|
|
111
|
-
} else {
|
|
112
|
-
style.height = typeof props.rowHeight === 'number'
|
|
113
|
-
? `${props.rowHeight}px`
|
|
114
|
-
: props.rowHeight
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
return style
|
|
118
|
-
}
|
|
119
|
-
</script>
|
|
120
|
-
|
|
121
|
-
<script lang="ts">
|
|
122
|
-
export default {
|
|
123
|
-
options: {
|
|
124
|
-
virtualHost: true,
|
|
125
|
-
styleIsolation: 'shared'
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
</script>
|
|
129
|
-
|
|
130
|
-
<style lang="scss" scoped>
|
|
131
|
-
.u-skeleton {
|
|
132
|
-
display: flex;
|
|
133
|
-
gap: $--spacing-md;
|
|
134
|
-
|
|
135
|
-
&--animate {
|
|
136
|
-
.u-skeleton__avatar,
|
|
137
|
-
.u-skeleton__title,
|
|
138
|
-
.u-skeleton__paragraph {
|
|
139
|
-
animation: skeleton-blink 1.2s ease-in-out infinite;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
&__avatar {
|
|
144
|
-
flex-shrink: 0;
|
|
145
|
-
background-color: $--bg-color-3;
|
|
146
|
-
border-radius: 50%;
|
|
147
|
-
|
|
148
|
-
&--circle {
|
|
149
|
-
border-radius: 50%;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
&--square {
|
|
153
|
-
border-radius: $--radius-sm;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
&__content {
|
|
158
|
-
flex: 1;
|
|
159
|
-
min-width: 0;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
&__title {
|
|
163
|
-
height: 20px;
|
|
164
|
-
margin-bottom: $--spacing-md;
|
|
165
|
-
background-color: $--bg-color-3;
|
|
166
|
-
border-radius: $--radius-sm;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
&__paragraphs {
|
|
170
|
-
display: flex;
|
|
171
|
-
flex-direction: column;
|
|
172
|
-
gap: $--spacing-sm;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
&__paragraph {
|
|
176
|
-
background-color: $--bg-color-3;
|
|
177
|
-
border-radius: $--radius-sm;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
@keyframes skeleton-blink {
|
|
182
|
-
0% {
|
|
183
|
-
opacity: 1;
|
|
184
|
-
}
|
|
185
|
-
50% {
|
|
186
|
-
opacity: 0.5;
|
|
187
|
-
}
|
|
188
|
-
100% {
|
|
189
|
-
opacity: 1;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
1
|
+
<template>
|
|
2
|
+
<view v-if="!loading" class="u-skeleton__content">
|
|
3
|
+
<slot />
|
|
4
|
+
</view>
|
|
5
|
+
<view v-else class="u-skeleton" :class="{ 'u-skeleton--animate': animate }">
|
|
6
|
+
<!-- 头像骨架 -->
|
|
7
|
+
<view
|
|
8
|
+
v-if="avatar"
|
|
9
|
+
class="u-skeleton__avatar"
|
|
10
|
+
:class="`u-skeleton__avatar--${avatarShape}`"
|
|
11
|
+
:style="avatarStyle"
|
|
12
|
+
/>
|
|
13
|
+
<!-- 内容区域 -->
|
|
14
|
+
<view class="u-skeleton__content">
|
|
15
|
+
<!-- 标题骨架 -->
|
|
16
|
+
<view
|
|
17
|
+
v-if="title"
|
|
18
|
+
class="u-skeleton__title"
|
|
19
|
+
:style="titleStyle"
|
|
20
|
+
/>
|
|
21
|
+
<!-- 段落骨架 -->
|
|
22
|
+
<view class="u-skeleton__paragraphs">
|
|
23
|
+
<view
|
|
24
|
+
v-for="(row, index) in rowList"
|
|
25
|
+
:key="index"
|
|
26
|
+
class="u-skeleton__paragraph"
|
|
27
|
+
:style="getRowStyle(index)"
|
|
28
|
+
/>
|
|
29
|
+
</view>
|
|
30
|
+
</view>
|
|
31
|
+
</view>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<script setup lang="ts">
|
|
35
|
+
import { computed } from 'vue'
|
|
36
|
+
|
|
37
|
+
type AvatarShape = 'circle' | 'square'
|
|
38
|
+
type TitleWidth = number | string
|
|
39
|
+
|
|
40
|
+
interface Props {
|
|
41
|
+
loading?: boolean
|
|
42
|
+
animate?: boolean
|
|
43
|
+
avatar?: boolean
|
|
44
|
+
avatarSize?: number | string
|
|
45
|
+
avatarShape?: AvatarShape
|
|
46
|
+
title?: boolean
|
|
47
|
+
titleWidth?: TitleWidth
|
|
48
|
+
row?: number
|
|
49
|
+
rowWidth?: number | string | (number | string)[]
|
|
50
|
+
rowHeight?: number | string | (number | string)[]
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
54
|
+
loading: true,
|
|
55
|
+
animate: true,
|
|
56
|
+
avatar: false,
|
|
57
|
+
avatarSize: 40,
|
|
58
|
+
avatarShape: 'circle',
|
|
59
|
+
title: true,
|
|
60
|
+
titleWidth: '40%',
|
|
61
|
+
row: 3,
|
|
62
|
+
rowWidth: '100%',
|
|
63
|
+
rowHeight: 16
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
const avatarStyle = computed(() => {
|
|
67
|
+
const size = typeof props.avatarSize === 'number'
|
|
68
|
+
? `${props.avatarSize}px`
|
|
69
|
+
: props.avatarSize
|
|
70
|
+
return {
|
|
71
|
+
width: size,
|
|
72
|
+
height: size
|
|
73
|
+
}
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
const titleStyle = computed(() => {
|
|
77
|
+
const width = typeof props.titleWidth === 'number'
|
|
78
|
+
? `${props.titleWidth}px`
|
|
79
|
+
: props.titleWidth
|
|
80
|
+
return { width }
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
const rowList = computed(() => {
|
|
84
|
+
return Array.from({ length: props.row }, (_, i) => i)
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
const getRowStyle = (index: number) => {
|
|
88
|
+
const style: Record<string, string> = {}
|
|
89
|
+
|
|
90
|
+
// 处理宽度
|
|
91
|
+
if (Array.isArray(props.rowWidth)) {
|
|
92
|
+
const width = props.rowWidth[index]
|
|
93
|
+
if (width !== undefined) {
|
|
94
|
+
style.width = typeof width === 'number' ? `${width}px` : width
|
|
95
|
+
}
|
|
96
|
+
} else if (index === props.row - 1 && props.rowWidth === '100%') {
|
|
97
|
+
// 最后一行默认 60% 宽度(如果是 100% 才处理)
|
|
98
|
+
style.width = '60%'
|
|
99
|
+
} else {
|
|
100
|
+
style.width = typeof props.rowWidth === 'number'
|
|
101
|
+
? `${props.rowWidth}px`
|
|
102
|
+
: props.rowWidth
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// 处理高度
|
|
106
|
+
if (Array.isArray(props.rowHeight)) {
|
|
107
|
+
const height = props.rowHeight[index]
|
|
108
|
+
if (height !== undefined) {
|
|
109
|
+
style.height = typeof height === 'number' ? `${height}px` : height
|
|
110
|
+
}
|
|
111
|
+
} else {
|
|
112
|
+
style.height = typeof props.rowHeight === 'number'
|
|
113
|
+
? `${props.rowHeight}px`
|
|
114
|
+
: props.rowHeight
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return style
|
|
118
|
+
}
|
|
119
|
+
</script>
|
|
120
|
+
|
|
121
|
+
<script lang="ts">
|
|
122
|
+
export default {
|
|
123
|
+
options: {
|
|
124
|
+
virtualHost: true,
|
|
125
|
+
styleIsolation: 'shared'
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
</script>
|
|
129
|
+
|
|
130
|
+
<style lang="scss" scoped>
|
|
131
|
+
.u-skeleton {
|
|
132
|
+
display: flex;
|
|
133
|
+
gap: $--spacing-md;
|
|
134
|
+
|
|
135
|
+
&--animate {
|
|
136
|
+
.u-skeleton__avatar,
|
|
137
|
+
.u-skeleton__title,
|
|
138
|
+
.u-skeleton__paragraph {
|
|
139
|
+
animation: skeleton-blink 1.2s ease-in-out infinite;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
&__avatar {
|
|
144
|
+
flex-shrink: 0;
|
|
145
|
+
background-color: $--bg-color-3;
|
|
146
|
+
border-radius: 50%;
|
|
147
|
+
|
|
148
|
+
&--circle {
|
|
149
|
+
border-radius: 50%;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
&--square {
|
|
153
|
+
border-radius: $--radius-sm;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
&__content {
|
|
158
|
+
flex: 1;
|
|
159
|
+
min-width: 0;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
&__title {
|
|
163
|
+
height: 20px;
|
|
164
|
+
margin-bottom: $--spacing-md;
|
|
165
|
+
background-color: $--bg-color-3;
|
|
166
|
+
border-radius: $--radius-sm;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
&__paragraphs {
|
|
170
|
+
display: flex;
|
|
171
|
+
flex-direction: column;
|
|
172
|
+
gap: $--spacing-sm;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
&__paragraph {
|
|
176
|
+
background-color: $--bg-color-3;
|
|
177
|
+
border-radius: $--radius-sm;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
@keyframes skeleton-blink {
|
|
182
|
+
0% {
|
|
183
|
+
opacity: 1;
|
|
184
|
+
}
|
|
185
|
+
50% {
|
|
186
|
+
opacity: 0.5;
|
|
187
|
+
}
|
|
188
|
+
100% {
|
|
189
|
+
opacity: 1;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
192
|
</style>
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
:class="{ 'u-tabbar__center-btn--active': modelValue === centerTab.value }"
|
|
30
30
|
@click="switchTab(centerTab.value)"
|
|
31
31
|
>
|
|
32
|
-
<text class="u-tabbar__center-brand"
|
|
32
|
+
<text class="u-tabbar__center-brand">
|
|
33
33
|
{{ centerBrand }}
|
|
34
34
|
</text>
|
|
35
|
-
<text class="u-tabbar__center-text"
|
|
35
|
+
<text class="u-tabbar__center-text">
|
|
36
36
|
{{ centerLabel }}
|
|
37
37
|
</text>
|
|
38
38
|
</view>
|
|
@@ -166,7 +166,6 @@ $--paper: #ffffff;
|
|
|
166
166
|
|
|
167
167
|
// Tab按钮
|
|
168
168
|
&__tab-btn {
|
|
169
|
-
flex: 1;
|
|
170
169
|
height: 40px;
|
|
171
170
|
border-radius: 20px;
|
|
172
171
|
background: transparent;
|
|
@@ -178,7 +177,7 @@ $--paper: #ffffff;
|
|
|
178
177
|
transition: all 200ms ease;
|
|
179
178
|
white-space: nowrap;
|
|
180
179
|
overflow: hidden;
|
|
181
|
-
|
|
180
|
+
padding: 0 16px;
|
|
182
181
|
|
|
183
182
|
&--active {
|
|
184
183
|
background: $--paper;
|