chore: establish V1.1 recovery baseline
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Loading 加载(规范 §21 推荐列表加载状态)
|
||||
*
|
||||
* 两种形态:
|
||||
* - mode="spinner":圆形旋转(页面级首次加载)
|
||||
* - mode="skeleton":骨架屏(列表渐进加载,避免抖动)
|
||||
* 用法:
|
||||
* <ui-loading mode="spinner" text="正在为你挑选…" />
|
||||
* <ui-loading mode="skeleton" rows="3" />
|
||||
*/
|
||||
Component({
|
||||
options: { addGlobalClass: true },
|
||||
properties: {
|
||||
mode: { type: String, value: 'spinner' }, // spinner|skeleton
|
||||
text: { type: String, value: '' },
|
||||
rows: { type: Number, value: 3 }, // skeleton 模式行数
|
||||
inline: { type: Boolean, value: false }, // 是否行内显示
|
||||
},
|
||||
data: {
|
||||
rowList: [],
|
||||
},
|
||||
observers: {
|
||||
rows(n) {
|
||||
const arr = [];
|
||||
for (let i = 0; i < n; i++) arr.push(i);
|
||||
this.setData({ rowList: arr });
|
||||
},
|
||||
},
|
||||
lifetimes: {
|
||||
attached() {
|
||||
const arr = [];
|
||||
for (let i = 0; i < this.data.rows; i++) arr.push(i);
|
||||
this.setData({ rowList: arr });
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<view class="ui-loading {{inline ? 'ui-loading--inline' : 'ui-loading--block'}}">
|
||||
<block wx:if="{{mode === 'spinner'}}">
|
||||
<view class="ui-loading__spinner">
|
||||
<view class="ui-loading__spinner-ring"></view>
|
||||
</view>
|
||||
<text wx:if="{{text}}" class="ui-loading__text">{{text}}</text>
|
||||
</block>
|
||||
<block wx:elif="{{mode === 'skeleton'}}">
|
||||
<view class="ui-loading__skeleton">
|
||||
<view wx:for="{{rowList}}" wx:key="*this" class="ui-loading__skeleton-row">
|
||||
<view class="ui-loading__skeleton-avatar"></view>
|
||||
<view class="ui-loading__skeleton-content">
|
||||
<view class="ui-loading__skeleton-line ui-loading__skeleton-line--title"></view>
|
||||
<view class="ui-loading__skeleton-line ui-loading__skeleton-line--meta"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
@@ -0,0 +1,94 @@
|
||||
.ui-loading--block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: var(--spacing-8) var(--spacing-page-x);
|
||||
}
|
||||
.ui-loading--inline {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
.ui-loading__spinner {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.ui-loading__spinner-ring {
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
border-radius: 50%;
|
||||
border: 4rpx solid var(--color-divider);
|
||||
border-top-color: var(--color-primary);
|
||||
animation: ui-loading-spin 0.8s linear infinite;
|
||||
}
|
||||
@keyframes ui-loading-spin {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
.ui-loading__text {
|
||||
margin-top: var(--spacing-3);
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--color-text-tertiary);
|
||||
}
|
||||
|
||||
/* Skeleton */
|
||||
.ui-loading__skeleton {
|
||||
width: 100%;
|
||||
}
|
||||
.ui-loading__skeleton-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: var(--spacing-3) var(--spacing-page-x);
|
||||
background: var(--color-bg-card);
|
||||
border-bottom: 1rpx solid var(--color-divider);
|
||||
}
|
||||
.ui-loading__skeleton-avatar {
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
border-radius: 50%;
|
||||
background: var(--color-bg-disabled);
|
||||
margin-right: var(--spacing-3);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.ui-loading__skeleton-content {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
.ui-loading__skeleton-line {
|
||||
height: 24rpx;
|
||||
background: var(--color-bg-disabled);
|
||||
border-radius: var(--radius-sm);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.ui-loading__skeleton-line--title {
|
||||
width: 40%;
|
||||
margin-bottom: var(--spacing-2);
|
||||
}
|
||||
.ui-loading__skeleton-line--meta {
|
||||
width: 70%;
|
||||
}
|
||||
/* shimmer */
|
||||
.ui-loading__skeleton-line::after,
|
||||
.ui-loading__skeleton-avatar::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
transparent 0%,
|
||||
rgba(255, 255, 255, 0.55) 50%,
|
||||
transparent 100%
|
||||
);
|
||||
animation: ui-loading-shimmer 1.4s ease-in-out infinite;
|
||||
}
|
||||
@keyframes ui-loading-shimmer {
|
||||
0% { transform: translateX(-100%); }
|
||||
100% { transform: translateX(100%); }
|
||||
}
|
||||
Reference in New Issue
Block a user