feat: 新增 ui-skeleton 骨架屏组件 (card / list-row / circle)
This commit is contained in:
@@ -0,0 +1,21 @@
|
|||||||
|
Component({
|
||||||
|
properties: {
|
||||||
|
variant: { type: String, value: 'card' },
|
||||||
|
count: { type: Number, value: 1 },
|
||||||
|
active: { type: Boolean, value: true }
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
_minDisplayShown: false
|
||||||
|
},
|
||||||
|
lifetimes: {
|
||||||
|
attached() {
|
||||||
|
// 200ms 最小显示,避免骨架闪一下
|
||||||
|
this._minTimer = setTimeout(() => {
|
||||||
|
this.setData({ _minDisplayShown: true })
|
||||||
|
}, 200)
|
||||||
|
},
|
||||||
|
detached() {
|
||||||
|
if (this._minTimer) clearTimeout(this._minTimer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"component": true,
|
||||||
|
"usingComponents": {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<view class="skeleton {{active ? 'skeleton--active' : ''}}" wx:if="{{_minDisplayShown || !active}}">
|
||||||
|
<!-- card variant -->
|
||||||
|
<block wx:if="{{variant === 'card'}}">
|
||||||
|
<view class="sk-card">
|
||||||
|
<view class="sk-bar sk-bar--title"></view>
|
||||||
|
<view class="sk-bar sk-bar--body"></view>
|
||||||
|
<view class="sk-bar sk-bar--small"></view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
|
||||||
|
<!-- list-row variant -->
|
||||||
|
<block wx:elif="{{variant === 'list-row'}}">
|
||||||
|
<view class="sk-list" wx:for="{{count}}" wx:key="*this">
|
||||||
|
<view class="sk-circle"></view>
|
||||||
|
<view class="sk-list-text">
|
||||||
|
<view class="sk-bar sk-bar--title"></view>
|
||||||
|
<view class="sk-bar sk-bar--small"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
|
||||||
|
<!-- circle variant (timer) -->
|
||||||
|
<block wx:elif="{{variant === 'circle'}}">
|
||||||
|
<view class="sk-circle sk-circle--big">
|
||||||
|
<view class="sk-bar sk-bar--center"></view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
</view>
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
.skeleton {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton--active .sk-bar,
|
||||||
|
.skeleton--active .sk-circle {
|
||||||
|
animation: skShimmer 1.4s ease-in-out infinite;
|
||||||
|
background: linear-gradient(90deg,
|
||||||
|
rgba(0, 0, 0, 0.06) 0%,
|
||||||
|
rgba(0, 0, 0, 0.12) 50%,
|
||||||
|
rgba(0, 0, 0, 0.06) 100%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes skShimmer {
|
||||||
|
0% { background-position: 200% 0; }
|
||||||
|
100% { background-position: -200% 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-bar {
|
||||||
|
height: 24rpx;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
background-color: rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-bar--title { width: 60%; height: 32rpx; }
|
||||||
|
.sk-bar--body { width: 100%; }
|
||||||
|
.sk-bar--small { width: 40%; height: 20rpx; margin-bottom: 0; }
|
||||||
|
.sk-bar--center { width: 60%; height: 40rpx; }
|
||||||
|
|
||||||
|
.sk-card {
|
||||||
|
background: var(--card-bg, #FFFFFF);
|
||||||
|
border-radius: 24rpx;
|
||||||
|
padding: 32rpx;
|
||||||
|
box-shadow: 0 2rpx 16rpx rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-circle {
|
||||||
|
width: 64rpx;
|
||||||
|
height: 64rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: rgba(0, 0, 0, 0.08);
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-circle--big {
|
||||||
|
width: 360rpx;
|
||||||
|
height: 360rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-list {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 24rpx 0;
|
||||||
|
gap: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-list-text {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dark mode */
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.sk-card { background: var(--card-bg, #1C1C1E); }
|
||||||
|
.skeleton--active .sk-bar,
|
||||||
|
.skeleton--active .sk-circle {
|
||||||
|
background: linear-gradient(90deg,
|
||||||
|
rgba(255, 255, 255, 0.05) 0%,
|
||||||
|
rgba(255, 255, 255, 0.10) 50%,
|
||||||
|
rgba(255, 255, 255, 0.05) 100%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
}
|
||||||
|
.sk-bar,
|
||||||
|
.sk-circle {
|
||||||
|
background-color: rgba(255, 255, 255, 0.06);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user