feat(web): 对齐 Alright 主题视觉规范(配色/字体/图标/背景/动效),并补充设计规范文档
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
import { categoryCount, type Category } from '../../data/types'
|
||||
import { ArrowLeftIcon } from '../common/Icon'
|
||||
import { AppGrid } from './AppGrid'
|
||||
import { CesCardGrid } from './CesCardGrid'
|
||||
import { GroupBlock } from './GroupBlock'
|
||||
import { PosterGrid } from './PosterGrid'
|
||||
|
||||
/**
|
||||
* 分类明细视图:返回条 + 面包屑 + hero(图标 / 标题 / 数量)+ 内容区。
|
||||
*
|
||||
* 内容区按分类类型切换:
|
||||
* - apps:指定分组时只渲染该组,否则单组扁平渲染、多组带小标题分组渲染;
|
||||
* - posters:6 列海报;
|
||||
* - articles:上图下文白卡网格。
|
||||
*/
|
||||
type DetailViewProps = {
|
||||
category: Category
|
||||
/** 从侧栏子菜单进入时指定的分组 */
|
||||
groupId?: string
|
||||
onBack: () => void
|
||||
/** 点击卡片 / 海报进入条目详情 */
|
||||
onOpenItem: (itemId: string) => void
|
||||
}
|
||||
|
||||
export function DetailView({ category, groupId, onBack, onOpenItem }: DetailViewProps) {
|
||||
const groups = category.kind === 'apps' ? category.groups : []
|
||||
const activeGroup =
|
||||
groupId !== undefined ? groups.find((group) => group.id === groupId) : undefined
|
||||
|
||||
const title = activeGroup?.name ?? category.title
|
||||
const count = activeGroup !== undefined ? activeGroup.items.length : categoryCount(category)
|
||||
const breadcrumb =
|
||||
activeGroup !== undefined
|
||||
? `首页 / ${category.title} / ${activeGroup.name}`
|
||||
: `首页 / ${category.title}`
|
||||
|
||||
function renderBody() {
|
||||
if (category.kind === 'posters') {
|
||||
return <PosterGrid items={category.items} variant="detail" onOpen={onOpenItem} />
|
||||
}
|
||||
|
||||
if (category.kind === 'articles') {
|
||||
return <CesCardGrid items={category.items} onOpen={onOpenItem} />
|
||||
}
|
||||
|
||||
if (activeGroup !== undefined) {
|
||||
return <AppGrid items={activeGroup.items} variant="detail" onOpen={onOpenItem} />
|
||||
}
|
||||
|
||||
if (category.groups.length === 1) {
|
||||
return <AppGrid items={category.groups[0].items} variant="detail" onOpen={onOpenItem} />
|
||||
}
|
||||
|
||||
if (category.groups.length === 0) {
|
||||
return <p className="section-empty">{category.emptyText ?? '暂无内容'}</p>
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{category.groups.map((group) => (
|
||||
<GroupBlock key={group.id} group={group} onOpen={onOpenItem} />
|
||||
))}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="detail-view">
|
||||
<div className="detail-nav card-box">
|
||||
<button type="button" className="detail-back" onClick={onBack}>
|
||||
<ArrowLeftIcon />
|
||||
返回首页
|
||||
</button>
|
||||
<span className="detail-breadcrumb">{breadcrumb}</span>
|
||||
</div>
|
||||
|
||||
<div className="detail-hero">
|
||||
<span className="detail-hero-icon" aria-hidden="true">
|
||||
{category.icon}
|
||||
</span>
|
||||
<h2 className="detail-hero-title">{title}</h2>
|
||||
<span className="detail-hero-count">[{count}]</span>
|
||||
</div>
|
||||
|
||||
{renderBody()}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user