feat(web): 对齐 Alright 主题视觉规范(配色/字体/图标/背景/动效),并补充设计规范文档

This commit is contained in:
2026-10-22 20:27:10 +08:00
parent e522a98f6f
commit 386c0f77c7
50 changed files with 6344 additions and 1094 deletions
@@ -0,0 +1,122 @@
import type { ItemDetailModel } from '../../data/detail'
import type { RelatedItem } from '../../data/types'
import { ExternalIcon, EyeIcon, ShareIcon, ThumbUpIcon } from '../common/Icon'
import { ArrowLeftIcon } from '../common/Icon'
import { RelatedList } from './RelatedList'
/**
* 条目详情页:应用与电影共用。
*
* 版式:标题 + 主图(方形头像 / 竖版海报)+ 标签行 + 一句话评价 + 正文
* + 操作条(浏览 / 点赞 / 分享 / 跳转)+ 可选横幅 + 「推荐阅读」。
* 具体形态由 ItemDetailModel 决定,这里不判断条目类型。
*/
type ItemDetailViewProps = {
breadcrumb: string
model: ItemDetailModel
related: RelatedItem[]
onBack: () => void
onOpenItem: (itemId: string) => void
}
export function ItemDetailView({
breadcrumb,
model,
related,
onBack,
onOpenItem,
}: ItemDetailViewProps) {
return (
<div className="detail-view item-view">
<div className="detail-nav card-box">
<button type="button" className="detail-back" onClick={onBack}>
<ArrowLeftIcon />
返回
</button>
<span className="detail-breadcrumb">{breadcrumb}</span>
</div>
<article className="item-card card-box">
<h2 className="item-title">
{model.title}
<button type="button" className="item-edit" disabled title="编辑功能待接入">
[编辑]
</button>
</h2>
<div className={`item-cover item-cover--${model.shape}`}>
{model.cover !== undefined ? (
<img src={model.cover} alt={model.title} loading="lazy" />
) : (
<span className="item-cover-letter">{model.fallbackIcon ?? '•'}</span>
)}
</div>
{model.tags.length > 0 && (
<div className="item-tags">
{model.tags.map((tag) => (
<span className="item-tag" key={tag}>
{tag}
</span>
))}
</div>
)}
{model.comment !== undefined && (
<div className="item-quote">
<span className="item-quote-mark" aria-hidden="true">
“
</span>
<p className="item-quote-text">{model.comment}</p>
</div>
)}
{model.paragraphs.map((paragraph, index) => (
<p className="item-desc" key={`${index}-${paragraph.slice(0, 8)}`}>
{paragraph}
</p>
))}
<div className="item-actions">
<span className="item-stat" title="浏览量">
<EyeIcon />
<em>{model.views}</em>
</span>
<span className="item-stat" title="点赞数">
<ThumbUpIcon />
<em>{model.likes}</em>
</span>
<button
type="button"
className="item-stat item-stat--icon"
title="分享(待接入)"
aria-label="分享"
>
<ShareIcon />
</button>
{/* 占位数据没有真实地址时,按钮置灰而不是打开空白页 */}
{model.href === '#' ? (
<button type="button" className="item-jump" disabled title="暂无跳转地址">
跳转到
<ExternalIcon />
</button>
) : (
<a className="item-jump" href={model.href} target="_blank" rel="noreferrer">
跳转到
<ExternalIcon />
</a>
)}
</div>
{model.banner !== undefined && (
<img className="item-banner" src={model.banner} alt="" loading="lazy" />
)}
</article>
<RelatedList items={related} onOpen={onOpenItem} />
</div>
)
}