feat(fe): 新增 seg-tabs 与 stat-ring 组件

seg-tabs 合并三套长得像但尺寸各不同的横向切换:plan 的 .inline-tabs
(灰槽白块)、community 的 .feed-tab(白药丸+阴影)、record 的 .rf-chip
(白药丸无阴影,高度还差 10rpx)。variant="solid|pill" 二选一,items
同时支持字符串数组和 {key,label} 数组。

stat-ring 是首页门面用的完成度环。用 SVG data-uri 画,和 record 页的
体重折线图同一套路——canvas 在 scroll-view 里的层级、滚动跟随和截图
行为全是坑。中心内容走 slot。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Blizzard
2026-07-29 10:36:35 +08:00
parent 91caac1b92
commit 15ff59e6db
9 changed files with 170 additions and 0 deletions
+38
View File
@@ -0,0 +1,38 @@
// 横向切换控件。此前有三套长得像但尺寸各不同的实现:
// plan 的 .inline-tabs(灰槽 + 白块)、community 的 .feed-tab(白药丸 + 橙选中 + 阴影)、
// record 的 .rf-chip(白药丸 + 橙选中 + 无阴影,高度还差 10rpx)
// 这里合成一个:variant="solid" 对应灰槽白块,variant="pill" 对应横滑药丸。
//
// items 支持两种写法:
// ['推荐','关注','经验'] —— current 传下标
// [{key:'',label:'全部'},{key:'weight',label:'体重'}] —— current 传 key
Component({
options: { addGlobalClass: true },
properties: {
items: { type: Array, value: [] },
current: { type: null, value: 0 },
variant: { type: String, value: 'pill' },
},
data: { list: [] },
observers: {
'items,current': function (items, current) {
const byKey = typeof current === 'string';
const list = (items || []).map((it, i) => {
const obj = it && typeof it === 'object';
const key = obj ? it.key : i;
return {
key,
label: obj ? it.label : it,
active: byKey ? key === current : i === Number(current),
};
});
this.setData({ list });
},
},
methods: {
onTap(e) {
const { index, key } = e.currentTarget.dataset;
this.triggerEvent('change', { index: Number(index), key });
},
},
});
+4
View File
@@ -0,0 +1,4 @@
{
"component": true,
"usingComponents": {}
}
+9
View File
@@ -0,0 +1,9 @@
<scroll-view wx:if="{{variant === 'pill'}}" class="st st-pill" scroll-x="{{true}}" enhanced="{{true}}" show-scrollbar="{{false}}">
<view wx:for="{{list}}" wx:key="key" class="st-item {{item.active ? 'on' : ''}}"
data-index="{{index}}" data-key="{{item.key}}" bindtap="onTap">{{item.label}}</view>
</scroll-view>
<view wx:else class="st st-solid">
<view wx:for="{{list}}" wx:key="key" class="st-item {{item.active ? 'on' : ''}}"
data-index="{{index}}" data-key="{{item.key}}" bindtap="onTap">{{item.label}}</view>
</view>
+21
View File
@@ -0,0 +1,21 @@
.st{white-space:nowrap}
/* 横滑药丸:数量不定、可滚动(社区分类、记录类型筛选) */
.st-pill{padding:0 0 var(--sp-4)}
.st-pill .st-item{
display:inline-block;height:var(--h-sm);line-height:var(--h-sm);padding:0 var(--sp-4);
margin-right:var(--sp-2);border-radius:var(--r-full);border:1rpx solid var(--line);
background:#fff;color:var(--muted);font-size:var(--fs-sm);font-weight:var(--fw-b);
}
.st-pill .st-item.on{color:var(--primary-dark);background:var(--primary-soft);border-color:var(--primary-line)}
/* 灰槽白块:数量固定的互斥视图(计划页三段) */
.st-solid{
display:flex;gap:var(--sp-1);padding:var(--sp-1);border-radius:var(--r-md);
background:#EFE8DE;margin-bottom:var(--sp-4);
}
.st-solid .st-item{
flex:1;height:var(--h-sm);line-height:var(--h-sm);text-align:center;border-radius:var(--r-sm);
color:var(--muted);font-size:var(--fs-md);font-weight:var(--fw-b);
}
.st-solid .st-item.on{background:#fff;color:var(--primary-dark)}