fix: 素材库桌面一行四卡,数字与文字分开

This commit is contained in:
chenpei 2026-08-17 21:59:36 +08:00
parent ed7c338537
commit e1669b90b6
3 changed files with 26 additions and 26 deletions

View File

@ -90,11 +90,11 @@ function FilterPanel(props: FilterPanelProps) {
const activeFilterCount = [selectedMaterialType, selectedCategory, selectedScene, selectedPlatform, selectedProductCategory, selectedMonth].filter(Boolean).length
const tabBase = 'relative shrink-0 whitespace-nowrap pb-3 text-[15px] tracking-[-0.02em] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#1a1c1d]/70 focus-visible:ring-offset-2 rounded-sm'
const tabActive = 'text-[#1a1c1d]'
const tabInactive = 'text-[#86898e] hover:text-[#1a1c1d]'
const tabInactive = 'text-[#6b7075] hover:text-[#1a1c1d]'
const chipBase = 'text-[14px] tracking-[-0.02em] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#1a1c1d]/70 focus-visible:ring-offset-2 rounded-sm'
const chipActive = 'text-[#1a1c1d]'
const chipInactive = 'text-[#86898e] hover:text-[#1a1c1d]'
const countMuted = (active: boolean) => (active ? 'text-[#6b7075]' : 'text-[#86898e]')
const chipInactive = 'text-[#6b7075] hover:text-[#1a1c1d]'
const countClass = 'font-en text-[12px] font-medium tabular-nums tracking-[0.08em] text-[#86898e]'
const countText = (value: number) => (facetsLoading ? '…' : value.toLocaleString('zh-CN'))
const rankedTypes = useMemo(() => {
const hasCounts = materialTypes.some((type) => (type.count || 0) > 0)
@ -212,7 +212,7 @@ function FilterPanel(props: FilterPanelProps) {
const renderTypeTab = (label: string, count: number, active: boolean, onClick: () => void) => (
<button onClick={onClick} className={`${tabBase} ${active ? tabActive : tabInactive}`}>
{label}
<span className={`ml-2 font-en text-[14px] tabular-nums ${countMuted(active)}`}>{countText(count)}</span>
<span className={`ml-2 ${countClass}`}>{countText(count)}</span>
{active && <span aria-hidden="true" className="absolute inset-x-0 -bottom-px h-px bg-[#1a1c1d]" />}
</button>
)
@ -241,7 +241,7 @@ function FilterPanel(props: FilterPanelProps) {
className={`${tabBase} ${moreActive || moreOpen ? tabActive : tabInactive}`}
>
更多
<span className={`ml-2 font-en text-[14px] tabular-nums ${countMuted(moreActive || moreOpen)}`}>{overflowTypes.length}</span>
<span className={`ml-2 ${countClass}`}>{overflowTypes.length}</span>
{(moreActive || moreOpen) && <span aria-hidden="true" className="absolute inset-x-0 -bottom-px h-px bg-[#1a1c1d]" />}
</button>
{moreOpen && (
@ -257,7 +257,7 @@ function FilterPanel(props: FilterPanelProps) {
className={`flex w-full items-baseline justify-between gap-6 px-4 py-2.5 text-left text-[14px] tracking-[-0.02em] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#1a1c1d]/70 ${active ? 'text-[#1a1c1d]' : 'text-[#6b7075] hover:bg-[#fafafa] hover:text-[#1a1c1d]'}`}
>
<span>{type.label}</span>
<span className={`font-en text-[13px] tabular-nums ${countMuted(active)}`}>{countText(type.count || 0)}</span>
<span className={countClass}>{countText(type.count || 0)}</span>
</button>
)
})}
@ -271,11 +271,11 @@ function FilterPanel(props: FilterPanelProps) {
</div>
<div aria-hidden="true" className="pointer-events-none absolute left-0 top-0 h-0 w-0 overflow-hidden">
<div ref={measureRef} className="flex w-max items-end gap-x-8 whitespace-nowrap">
<span className={tabBase}>全部<span className="ml-2 font-en text-[14px] tabular-nums">{countText(totals.materialType)}</span></span>
<span className={tabBase}>全部<span className={`ml-2 ${countClass}`}>{countText(totals.materialType)}</span></span>
{rankedTypes.map((type) => (
<span key={type.value} className={tabBase}>{type.label}<span className="ml-2 font-en text-[14px] tabular-nums">{countText(type.count || 0)}</span></span>
<span key={type.value} className={tabBase}>{type.label}<span className={`ml-2 ${countClass}`}>{countText(type.count || 0)}</span></span>
))}
<span className={tabBase}>更多<span className="ml-2 font-en text-[14px] tabular-nums">00</span></span>
<span className={tabBase}>更多<span className={`ml-2 ${countClass}`}>00</span></span>
</div>
</div>
</div>
@ -291,7 +291,7 @@ function FilterPanel(props: FilterPanelProps) {
</div>
<div className="mb-8 flex flex-wrap items-baseline justify-between gap-3">
<p className="text-[13px] text-[#86898e]">
共 <span className="font-en tabular-nums text-[#6b7075]">{facetsLoading ? '…' : materialsCount.toLocaleString('zh-CN')}</span> 条
共 <span className="font-en text-[15px] font-medium tabular-nums tracking-[0.06em] text-[#1a1c1d]">{facetsLoading ? '…' : materialsCount.toLocaleString('zh-CN')}</span> 条
{selectedMaterialType && <span className="sr-only">{facetsLoading ? '计数加载中' : `${materialsCount} 个素材`}</span>}
</p>
<div className="flex items-center gap-4 text-[13px]" role="group" aria-labelledby="materials-sort-label">
@ -310,35 +310,35 @@ function FilterPanel(props: FilterPanelProps) {
<div className="mb-6">
<h2 className="mb-3 text-[13px] text-[#6b7075]">使用店铺</h2>
<div className="flex flex-wrap gap-x-5 gap-y-2">
<button onClick={() => setSelectedCategory('')} className={`${chipBase} ${selectedCategory === '' ? chipActive : chipInactive}`}>全部<span className={`ml-1.5 font-en text-[13px] tabular-nums ${countMuted(selectedCategory === '')}`}>{countText(totals.category)}</span></button>
{rankedCategories.map((item) => <button key={item.id} onClick={() => setSelectedCategory(item.name === selectedCategory ? '' : item.name)} className={`${chipBase} ${selectedCategory === item.name ? chipActive : chipInactive}`}>{item.name}<span className={`ml-1.5 font-en text-[13px] tabular-nums ${countMuted(selectedCategory === item.name)}`}>{countText(item.count || 0)}</span></button>)}
<button onClick={() => setSelectedCategory('')} className={`${chipBase} ${selectedCategory === '' ? chipActive : chipInactive}`}>全部<span className={`ml-1.5 ${countClass}`}>{countText(totals.category)}</span></button>
{rankedCategories.map((item) => <button key={item.id} onClick={() => setSelectedCategory(item.name === selectedCategory ? '' : item.name)} className={`${chipBase} ${selectedCategory === item.name ? chipActive : chipInactive}`}>{item.name}<span className={`ml-1.5 ${countClass}`}>{countText(item.count || 0)}</span></button>)}
</div>
</div>
<div className="mb-6">
<h2 className="mb-3 text-[13px] text-[#6b7075]">场景类别</h2>
<div className="flex flex-wrap gap-x-5 gap-y-2">
<button onClick={() => setSelectedScene('')} className={`${chipBase} ${selectedScene === '' ? chipActive : chipInactive}`}>全部<span className={`ml-1.5 font-en text-[13px] tabular-nums ${countMuted(selectedScene === '')}`}>{countText(totals.scene)}</span></button>
{rankedScenes.map((item) => <button key={item.id} onClick={() => setSelectedScene(item.name === selectedScene ? '' : item.name)} className={`${chipBase} ${selectedScene === item.name ? chipActive : chipInactive}`}>{item.name}<span className={`ml-1.5 font-en text-[13px] tabular-nums ${countMuted(selectedScene === item.name)}`}>{countText(item.count || 0)}</span></button>)}
<button onClick={() => setSelectedScene('')} className={`${chipBase} ${selectedScene === '' ? chipActive : chipInactive}`}>全部<span className={`ml-1.5 ${countClass}`}>{countText(totals.scene)}</span></button>
{rankedScenes.map((item) => <button key={item.id} onClick={() => setSelectedScene(item.name === selectedScene ? '' : item.name)} className={`${chipBase} ${selectedScene === item.name ? chipActive : chipInactive}`}>{item.name}<span className={`ml-1.5 ${countClass}`}>{countText(item.count || 0)}</span></button>)}
</div>
</div>
{(rankedPlatforms.length > 0 || facetsLoading) && <div className="mb-6">
<h2 className="mb-3 text-[13px] text-[#6b7075]">平台分类</h2>
<div className="flex flex-wrap gap-x-5 gap-y-2">
<button onClick={() => setSelectedPlatform('')} className={`${chipBase} ${selectedPlatform === '' ? chipActive : chipInactive}`}>全部<span className={`ml-1.5 font-en text-[13px] tabular-nums ${countMuted(selectedPlatform === '')}`}>{countText(totals.platform)}</span></button>
{rankedPlatforms.map((item) => <button key={item.id} onClick={() => setSelectedPlatform(item.name === selectedPlatform ? '' : item.name)} className={`${chipBase} ${selectedPlatform === item.name ? chipActive : chipInactive}`}>{item.name}<span className={`ml-1.5 font-en text-[13px] tabular-nums ${countMuted(selectedPlatform === item.name)}`}>{countText(item.count || 0)}</span></button>)}
<button onClick={() => setSelectedPlatform('')} className={`${chipBase} ${selectedPlatform === '' ? chipActive : chipInactive}`}>全部<span className={`ml-1.5 ${countClass}`}>{countText(totals.platform)}</span></button>
{rankedPlatforms.map((item) => <button key={item.id} onClick={() => setSelectedPlatform(item.name === selectedPlatform ? '' : item.name)} className={`${chipBase} ${selectedPlatform === item.name ? chipActive : chipInactive}`}>{item.name}<span className={`ml-1.5 ${countClass}`}>{countText(item.count || 0)}</span></button>)}
</div>
</div>}
{(rankedProductCategories.length > 0 || facetsLoading) && <div className="mb-6">
<h2 className="mb-3 text-[13px] text-[#6b7075]">产品类别</h2>
<div className="flex flex-wrap gap-x-5 gap-y-2">
<button onClick={() => setSelectedProductCategory('')} className={`${chipBase} ${selectedProductCategory === '' ? chipActive : chipInactive}`}>全部<span className={`ml-1.5 font-en text-[13px] tabular-nums ${countMuted(selectedProductCategory === '')}`}>{countText(totals.productCategory)}</span></button>
{rankedProductCategories.map((item) => <button key={item.id} onClick={() => setSelectedProductCategory(item.name === selectedProductCategory ? '' : item.name)} className={`${chipBase} ${selectedProductCategory === item.name ? chipActive : chipInactive}`}>{item.name}<span className={`ml-1.5 font-en text-[13px] tabular-nums ${countMuted(selectedProductCategory === item.name)}`}>{countText(item.count || 0)}</span></button>)}
<button onClick={() => setSelectedProductCategory('')} className={`${chipBase} ${selectedProductCategory === '' ? chipActive : chipInactive}`}>全部<span className={`ml-1.5 ${countClass}`}>{countText(totals.productCategory)}</span></button>
{rankedProductCategories.map((item) => <button key={item.id} onClick={() => setSelectedProductCategory(item.name === selectedProductCategory ? '' : item.name)} className={`${chipBase} ${selectedProductCategory === item.name ? chipActive : chipInactive}`}>{item.name}<span className={`ml-1.5 ${countClass}`}>{countText(item.count || 0)}</span></button>)}
</div>
</div>}
<div className="mb-6">
<h2 className="mb-3 text-[13px] text-[#6b7075]">上传时间</h2>
<div className="flex flex-wrap gap-x-5 gap-y-2">
<button onClick={() => setSelectedMonth('')} className={`${chipBase} ${selectedMonth === '' ? chipActive : chipInactive}`}>全部<span className={`ml-1.5 font-en text-[13px] tabular-nums ${countMuted(selectedMonth === '')}`}>{countText(totals.month)}</span></button>
<button onClick={() => setSelectedMonth('')} className={`${chipBase} ${selectedMonth === '' ? chipActive : chipInactive}`}>全部<span className={`ml-1.5 ${countClass}`}>{countText(totals.month)}</span></button>
{yearFacets.map((item) => (
<button
key={item.year}
@ -346,7 +346,7 @@ function FilterPanel(props: FilterPanelProps) {
className={`${chipBase} ${selectedMonth === item.year || selectedMonth.startsWith(`${item.year}-`) ? chipActive : chipInactive}`}
>
{item.year}
<span className={`ml-1.5 font-en text-[13px] tabular-nums ${countMuted(selectedMonth === item.year || selectedMonth.startsWith(`${item.year}-`))}`}>{countText(item.count)}</span>
<span className={`ml-1.5 ${countClass}`}>{countText(item.count)}</span>
</button>
))}
</div>
@ -361,7 +361,7 @@ function FilterPanel(props: FilterPanelProps) {
className={`${chipBase} ${selectedMonth === item.value ? chipActive : chipInactive}`}
>
{monthNumber}月
<span className={`ml-1.5 font-en text-[13px] tabular-nums ${countMuted(selectedMonth === item.value)}`}>{countText(item.count)}</span>
<span className={`ml-1.5 ${countClass}`}>{countText(item.count)}</span>
</button>
)
})}

View File

@ -591,9 +591,9 @@ export default function MaterialCard({
{materialDisplayTitle}
</h3>
<p className="mt-1.5 truncate text-[12px] leading-relaxed text-[#86898e]">
{fileSizeLabel && <><span>{fileSizeLabel}</span> · </>}
{fileSizeLabel && <><span className="font-en tabular-nums tracking-[0.04em]">{fileSizeLabel}</span> · </>}
{material.authorName && <><span>{material.authorName}</span> · </>}
<span>{format(new Date(material.createdAt), 'yyyy.MM.dd')}</span>
<span className="font-en tabular-nums tracking-[0.04em]">{format(new Date(material.createdAt), 'yyyy.MM.dd')}</span>
{material.materialType && <> · <span>{material.materialType}</span></>}
{material.categoryName && <> · <span>{material.categoryName}</span></>}
{material.sceneName && <> · <span>{material.sceneName}</span></>}
@ -661,7 +661,7 @@ export default function MaterialCard({
}`}
title={material.isLiked ? '取消点赞' : '点赞'}
>
点赞 <span>{material.likeCount}</span>
点赞 <span className="font-en text-[12px] tabular-nums tracking-[0.06em]">{material.likeCount}</span>
</button>
{session?.user && (
<button

View File

@ -47,7 +47,7 @@ interface MaterialGridProps {
function MaterialGridSkeleton() {
return (
<div
className="grid grid-cols-1 gap-x-8 gap-y-12 sm:grid-cols-2 lg:grid-cols-3"
className="grid grid-cols-1 gap-x-6 gap-y-10 sm:grid-cols-2 lg:grid-cols-4"
aria-busy="true"
aria-live="polite"
aria-label="素材列表加载中"
@ -119,7 +119,7 @@ export default function MaterialGrid({
</p>
</div>
) : (
<div className="grid grid-cols-1 gap-x-8 gap-y-12 sm:grid-cols-2 lg:grid-cols-3">
<div className="grid grid-cols-1 gap-x-6 gap-y-10 sm:grid-cols-2 lg:grid-cols-4">
{materials.slice(0, displayedCount).map((material) => (
<MaterialCard
key={material.id}