style(content): 明细页分组标题增加分区色条

- 分组标题与首页卡片统一为「色条 + 标题」,颜色取分区的 barColor
- 空分组不再在明细页占标题(后台仍保留)
This commit is contained in:
2026-10-30 19:42:18 +08:00
parent 58725caa95
commit 1a4a6a3655
3 changed files with 47 additions and 13 deletions
+14
View File
@@ -336,6 +336,20 @@
background-color: var(--su-color-primary); background-color: var(--su-color-primary);
} }
/* 明细页的分组标题:与首页卡片标题同一套「色条 + 标题」 */
.group-title {
display: flex;
align-items: center;
}
.group-bar {
width: 4px;
height: 16px;
margin-right: var(--su-space-2);
border-radius: 2px;
background-color: var(--su-color-primary);
}
/* ---------- 应用条目 ---------- */ /* ---------- 应用条目 ---------- */
.app-card { .app-card {
@@ -74,8 +74,10 @@ export function DetailView({ category, groupId, onNavigate, onOpenItem }: Detail
} }
const direct = (category.items ?? []) as RenderItem[] const direct = (category.items ?? []) as RenderItem[]
// 空分组不占篇幅(管理后台仍然保留,之后可以往里加条目)
const filledGroups = groups.filter((group) => group.items.length > 0)
if (groups.length === 0) { if (filledGroups.length === 0) {
return direct.length > 0 ? ( return direct.length > 0 ? (
renderItems(direct) renderItems(direct)
) : ( ) : (
@@ -83,19 +85,28 @@ export function DetailView({ category, groupId, onNavigate, onOpenItem }: Detail
) )
} }
if (groups.length === 1 && direct.length === 0) { if (filledGroups.length === 1 && direct.length === 0) {
return renderItems(groups[0].items) return renderItems(filledGroups[0].items)
} }
return ( return (
<Space direction="column" gap="lg" align="stretch"> <Space direction="column" gap="lg" align="stretch">
{groups.map((group) => ( {filledGroups.map((group) => (
<GroupBlock key={group.id} name={group.name}> <GroupBlock
key={group.id}
name={group.name}
barColor={category.barColor !== '' ? category.barColor : undefined}
>
{renderItems(group.items)} {renderItems(group.items)}
</GroupBlock> </GroupBlock>
))} ))}
{direct.length > 0 && ( {direct.length > 0 && (
<GroupBlock name="未分组">{renderItems(direct)}</GroupBlock> <GroupBlock
name="未分组"
barColor={category.barColor !== '' ? category.barColor : undefined}
>
{renderItems(direct)}
</GroupBlock>
)} )}
</Space> </Space>
) )
@@ -2,22 +2,31 @@ import { Space, Title } from '@stash/ui'
import type { ReactNode } from 'react' import type { ReactNode } from 'react'
/** /**
* 明细页的分组块:小标题 + 该组的内容网格。 * 明细页的分组块:色条 + 小标题 + 该组的内容网格。
* *
* 具体网格由调用方传入(应用 / 海报 / 图文共用同一层外壳), * 色条沿用分区的 `barColor`,与首页卡片标题保持同一套视觉语言;
* 这样三种类型的「分组」渲染方式保持一致。 * 具体网格由调用方传入(应用 / 海报 / 图文共用同一层外壳)。
*/ */
type GroupBlockProps = { type GroupBlockProps = {
name: string name: string
/** 分区色条颜色;缺省用主题主色 */
barColor?: string
children: ReactNode children: ReactNode
} }
export function GroupBlock({ name, children }: GroupBlockProps) { export function GroupBlock({ name, barColor, children }: GroupBlockProps) {
return ( return (
<Space direction="column" gap="sm" align="stretch" className="group-block"> <Space direction="column" gap="sm" align="stretch" className="group-block">
<div className="group-title">
<span
className="group-bar"
style={barColor !== undefined ? { backgroundColor: barColor } : undefined}
aria-hidden="true"
/>
<Title level={4} as="h3"> <Title level={4} as="h3">
{name} {name}
</Title> </Title>
</div>
{children} {children}
</Space> </Space>
) )